java 1.5 引入了
- 泛型
- 增强循环,可以使用迭代方式(也称foreach语句)
- 自动装箱与自动拆箱
- 枚举
- 可变参数
- 静态导入
- 线程并发库
- 内省
1. 泛型:
C++ 通过模板技术可以指定集合的元素类型,而Java在1.5之前一直没有相对应的功能。一个集合可以放任何类型的对象,相应地从集合里面拿对象的时候我们也 不得不对他们进行强制得类型转换。jdk1.5之后引入了泛型,它允许指定集合里元素的类型,这样你可以得到强类型在编译时刻进行类型检查的好处。
//给集合指定存入类型,上面这个集合在存入数据的时候必须存入String类型的数据,否则编译器会报错
List<String> strs = new ArrayList<String>();
2.增强for循环(for-each语句)
格式:for(ElementType element:arrayName){};
ElementType可以是数组或者实现了Iterable接口的集合类, 使用增强for循环的时候会忽略角标信息,所以在需要角标的时候最好还是使用传统的方式。
String [] strs = {'a','b','c'};
for(String s : strs){
System.out.println(s);
}
3.自动拆箱和装箱功能
什么意思呢?
自动装箱的过程:每当需要一种类型的对象时,这种基本类型就自动地封装到与它相同类型的包装中。
自动拆箱的过程:每当需要一个值时,被装箱对象中的值就被自动地提取出来,没必要再去调用intValue()和doubleValue()方法。
自动装箱,只需将该值赋给一个类型包装器引用,java会自动创建一个对象。
自动拆箱,只需将该对象值赋给一个基本类型即可。
java为了效率,定义了8中基本数据类型: byte short int long
char float double boolean 但是他们不是对象,没有指定的方法,所以他们有对应的封装类,而且内部定义了一些方法(定义泛型的时候用到基本数据类型的时候只能用其封装类)
java——类的包装器
类型包装器有:Double,Float,Long,Integer,Short,Character和Boolean
例如:
基本数据类型 ------------------- 封装类
byte -------------------- Byte
short -------------------- Short
int -------------------- Integer
long -------------------- Long
char -------------------- Character
float -------------------- Float
double -------------------- Double
boolean -------------------- Boolean
Integer intNum = 13; //自动装箱
int intNum2 = new Integer(13);//自动拆箱
//必须手动装箱拆箱
Integer intNum3 = new Integer(13); //手动装箱
int intNum4 = intNum3.intValue();//手动拆箱
自动装包:将基本类型转换成为对象,例如:int --> Integer
自动拆包:将对象转换成为基本数据类型,例如:Integer --> int
对于JDK1.5之前集合总不能存放基本数据类型的问题,现在也能够解决。
4.枚举
把集合里的对象元素一个一个提取出来。枚举类型使代码更具可读性,理解清晰,易于维护。枚举类型是强类型的,从而保证了系统安全性。而以类的静态字段实现的类似替代模型,不具有枚举的简单性和类型安全性。
简单的用法:JavaEnum简单的用法一般用于代表一组常用常量,可用来代表一类相同类型的常量值。
复杂用法:Java为枚举类型提供了一些内置的方法,同事枚举常量还可以有自己的方法。可以很方便的遍历枚举对象。
枚举类的定义格式:
enum 类名{
//枚举值
}
有些方法在运行时,它需要的数据不能是任意的,而必须是一定范围内的
值,有了枚举之后可以直接使用枚举解决。比如: 方向 , 性别 , 季节 ,星期等
枚举要注意的细节:
1.枚举类也是一个特殊的类。
2.枚举值默认的修饰符是public static final。
3.枚举值就是是枚举值所属的类的类型, 然后枚举值是指向了本类的对象的。
4.枚举类的构造方法默认的修饰符是private的。
5.枚举类可以定义自己的成员变量与成员函数。
6.枚举类可以自定义构造函数,但是构造函数的修饰符必须是private。
7.枚举类可以存在抽象的方法,但是枚举值必须要实现抽象的方法。
8.枚举值必须要位置枚举类的第一个语句。
9.枚举值可以用于switch语句
示例:
//定义代表交通灯的枚举
public enum MyEnum{
RED,GREEN,YELLOW
}
enum Sex{
man("男"){
@Override
public void run() {
System.out.println("男人在跑...");
}
},woman("女"){
@Override
public void run() {
System.out.println("女人在跑...");
}
}; //枚举值
String value; //成员变量
// public static final Sex man = new Sex();
//构造函数
private Sex(String value){
this.value = value;
}
//成员函数
public void getValue(){
System.out.println("value :"+ value);
}
public abstract void run();
}
public class Demo {
public static void main(String[] args) {
Sex sex = Sex.man; //获取到了枚举类的对象
sex.value = "男";
sex.getValue();
sex.run();
//结果 :value :男
男人在跑...
}
}
5.可变参数
什么意思呢?先举个例子:在JDK1.5以前,当我们要为一个方法传递多个类型相同的参数时,我们有两种方法解决,1.直接传递一个数组过去,2.有多少个参数就传递多少个参数。
例如:
public void printColor(String red,String green,String yellow){
}
或者
public void printColor(String[] colors){
}
这样编写方法参数虽然能够实现我们想要的效果,但是,这样是不是有点麻烦呢?再者,如果参数个数不确定,我们怎么办呢?Java JDK1.5为我们提供的可变参数就能够完美的解决这个问题。
可变参数其实就是维护了一个数组,此时可以使用可变参数,格式 类型... 变量名
例如:
public void add(int... nums){
int sum = 0;
for (int i : nums){
sum+=i;
}
System.out.println("和是: " + sum);
}
可以这样定义,什么意思呢?如果参数的类型相同,那么可以使用“类型+三个点,后面跟一个参数名称”的形式。这样的好处就是,只要参数类型相同,无论传递几个参数都没有限制
注意:可变参数必须是参数列表的最后一项(该特性对对象和基本数据类型都适用)
6.静态导入
优点:使用静态导入可以使被导入类的所有静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出他们的类名。(简化书写)
缺点:过度使用会降低代码的可读性
通过使用 import static,就可以不用指定 Constants 类名而直接使用静态成员,包括静态方法。
import xxxx 和 import static xxxx的区别是前者一般导入的是类文件如import java.util.Scanner;后者一般是导入静态的方法,import static java.lang.System.out
静态导入的格式:
import static 包名.类名.静态的成员;
静态导入要注意:
如果静态导入的成员与本类的成员存在同名的情况下,那么默认使用本类的静态成员,如果需要指定使用静态导入的成员,那么需要在静态成员前面加上类名。个人感觉静态导入还是少用比较好,包的机制有个重要的作用就是避免命名的问题。
import static java.lang.System.out;
public class Demo1 {
public static void main(String[] args) {
out.println("haha...");
}
}
7.线程并发库
线程并发库是Java1.5提出的关于多线程处理的高级功能,所在包:java.util.concurrent
包括:
①线程互斥
工具类描述:Lock,RedWriteLock
②线程通信
描述:Condition
③线程池
ExecutorService
④同步队列
ArrayBlockingQueue
⑤同步集合
ConcurrentHashMap,CopyOnWriteArrayList
⑥线程同步工具
Semaphore
Lock代替了Synchrinozed的使用,一个Lock可以设置多个Condition监视器,可以实现灵活的线程间通信。
关于线程并发库的内容还有很多(很重要),这里就不一一列举了,感兴趣的朋友可以查看一下帮助文档。
8.内省
是 Java语言对Bean类属性、事件的一种缺省处理方法。例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新 的值。通过getName/setName来访问name属性,这就是默认的规则。Java中提供了一套API用来访问某个属性的getter /setter方法,通过这些API可以使你不需要了解这个规则(但你最好还是要搞清楚),这些API存放于包java.beans中。
一 般的做法是通过类Introspector来获取某个对象的BeanInfo信息,然后通过BeanInfo来获取属性的描述器 (PropertyDescriptor),通过这个属性描述器就可以获取某个属性对应的getter/setter方法,然后我们就可以通过反射机制来 调用这些方法。
ReflectPoint pt1 = new ReflectPoint(3,5);
BeanInfo beanInfo = Introspector.getBeanInfo(pt1.getClass());
PropertyDescriptor[] pds = beanInfo.getPropertyDescriptors();
Object retVal = null;
for(PropertyDescriptor pd : pds){
Method methodGetX = pd.getReadMethod();
retVal = methodGetX.invoke(pt1);
}
参考文章:
http://www.jb51.net/article/94693.htm
http://www.jianshu.com/p/a0e06f171c05
http://blog.csdn.net/lgh1117/article/details/48947391