万丈高楼平地起,楼的高度取决于地基的牢固程度,虽然这些东西以前都学过,但却没有系统的整理过。借此机会好好梳理一下基础知识。
JDK1.5新增了许多新特性,这些特性包括泛型,for-each 循环,自动装包/拆包,枚举,可变参数, 静态导入 。使用这些特性有助于我们编写更加清晰,精悍,安全的代码。
下面我们简单介绍一下这些新特性。
????? 1.静态导入(Static Imports) 要使用用静态成员(方法和变量)我们必须给出提供这个方法的类。使用静态导入能使被导入类的所有静态变量和静态方法在当前类直接可见,使用这些静态成员无需再给出他们的类名。
import static java.lang.Math.*;…….i = max(1,7); //无需再写i = Math.max(1,7);
不过,过度使用这个特性也会一定程度上降低代码地可读性。
2.可变参数(Varargs) 可变参数使程序员能声明一个接受可变数目参数的方法。注意,可变参数只能出现在参数列表的最后,...位于变量类型和变量名之间,调用可变参数的方法时,编译器为该可变参数隐含创建一个数组,在方法体中以数组的形式访问可变参数,例如写一个计算几个数相加的方法
add(1,2);add(12,3,6);add(5,23,9);…
在JDK1.5之前,我们能用重载来实现,不过这样就需要写非常多的重载函数,显得不是非常有效。如果使用可变参数的话我们只需要一个函数就行了
public static int add(int i, int... args){
?????? int sum = i;
?????? for(int j=0; j<args.length; j++){
??????????? sum+=args[j];
?????? }
??????? return sum;
}
在引入可变参数以后,Java的反射包也更加方便使用了。对于c.getMethod("test", new Object[0]).invoke(c.newInstance(), new Object[0])),目前我们能这样写了c.getMethod("test").invoke(c.newInstance()),这样的代码比原来清晰了非常多。
3.For-Each循环 For-Each循环得加入简化了集合的遍历。假设我们要遍历一个集合对其中的元素进行一些处理。典型的代码为:
void processAll(Collection c){
????? for(Iterator i=c.iterator(); i.hasNext();){
MyClass myObject = (MyClass)i.next();
? myObject.process();
?????? }
?}
使用For-Each循环,我们能把代码改写成:
void processAll(Collection<MyClass> c){
???? for(MyClass myObject :c)
myObject.process();
}
这段代码要比上面清晰许多,并且避免了强制类型转换。
?????? public static int add(int i, int... args){
?????????? int sum = i;
?????????? for(int arg :args){
????????????? sum+=arg;
?????????? }
??????????? return sum;
??????? }
????? 4.自动装箱/拆箱(Autoboxing/unboxing) 自动装包/拆包大大方便了基本类型数据和他们包装类地使用。 自动装包:基本类型自动转为包装类.(int >> Integer) 自动拆包:包装类自动转为基本类型.(Integer >> int) 在JDK1.5之前,我们总是对集合不能存放基本类型而耿耿于怀,目前自动转换机制解决了我们的问题。
int a = 3;Collection c = new ArrayList();c.add(a);//自动转换成Integer.Integer b = new Integer(2);c.add(b + 2);
这里Integer先自动转换为int进行加法运算,然后int再次转换为Integer.
????? 附加知识点:享元模式——享元模式以共享的方式高效地支持大量的细粒度对象。享元对象能做到共享的关键是区分内蕴状态和外蕴状态,一个内蕴状态是存储在享元对象内部的,并不会随环境的变化而变化,一个外蕴状态是随环境变化而变化的,不可以共享。内蕴状态也可认为是类内部变量,而外蕴状态则是从外部传入的参数。
????? ............
????? Integer i1 = 126;? Integer i2 = 126;? System.out.println(i1==i2);.........结果为true, 而Integer i1 = 135;Integer i2 = 135;System.out.println(i1==i2);结果为false。原因是这样的,当基本类型的整数要装箱成为Integer对象的时候如果这个数值在一个字节之内(即-128——127之间),就会将这个数值在缓冲池中缓存起来,当下次要把一个整数装箱成为一个Integer对象的时候,会首先到这个缓冲池中去查找有没有这个值,如果有就直接用这个值,这样做能够节省内存空间,提升程序性能
???
5.枚举(Enums) JDK1.5加入了一个全新类型的“类”-枚举类型。为此JDK1.5引入了一个新关键字enmu. 我们能这样来定义一个枚举类型。
public enum Color{ Red, White, Blue}
然后能这样来使用Color myColor = Color.Red. 枚举类型还提供了两个有用的静态方法values()和valueOf(). 我们能非常方便地使用他们,例如
for (Color c : Color.values()) System.out.println(c);
关于枚举类型的的学习,以前听过马士兵老师的视频教程,感觉讲的还好也理解了怎么回事,今天再次复习,是听张孝祥老师的视频教程,感觉又有新收获,下面我总结一下以前不知道的关于枚举的知识点:
????? 张老师通过交通灯问题讲解“实现带有抽象方法的枚举”一节讲的尤为有趣,用类比的方法帮助我们理解是怎么回事。
????? public enum TrafficLamp{
?????????? RED(30){
?????????????????? public? TrafficLamp nextLamp(){
???????????????????????????????? return GREEN;
??????????????????? }
?????????? },
?????????? GREEN(45){
??????????????????? public? TrafficLamp nextLamp(){
???????????????????????????????? return YELLOW;
?????????????????????? }??
?????????? },
?????????? YELLOW(5){
??????????????????? public? TrafficLamp nextLamp(){
??????????????????????????????? return RED;
??????????????????? }??
?????????? };
?????????? public abstract TrafficLamp nextLamp();
?????????? private int time;
?????????? private TrafficLamp(int time){this.time = time;}
?????? }
这个显得有些复杂的枚举类型实际上可以通过类比 new Date(子类用来调用父类构造方法的参数){子类的代码,覆盖父类中定义的抽象方法}来理解。
?????
????? 6. 泛型(Generic) C++通过模板技术能指定集合的元素类型,而Java在1.5之前一直没有相对应的功能。一个集合能放所有类型的对象,相应地从集合里面拿对象的时候我们也不得不对他们进行强制得类型转换。猛虎引入了泛型,他允许指定集合里元素的类型,这样你能得到强类型在编译时刻进行类型检查的好处。
Collection<String> c = new ArrayList();c.add(new Date());
编译器会给出一个错误:
add(java.lang.String) in java.util.Collection<java.lang.String> cannot be applied to (java.util.Date)
?
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/lganggang131/archive/2010/12/27/6101363.aspx