Jdk5.0中出现的新特性

时间:2022-05-23 08:19:47

掌握jdk5.0中出现的新特性
1.泛型(Generics)
2.增强的"for"循环(Enhanced For loop)
3.自动装箱/自动拆箱(Autoboxing/unboxing)
4.类型安全的枚举(Type safe enums)
5.静态导入(Static import)
6.可变参数(Var args)

1.泛型(Generics)

泛型是JDK1.5中一个最重要的特征。通过引入泛型,我们将获得编译时类型的安全和运行时更小地抛出ClassCastExceptions的可能。

public class ArrayListTest {
    public static void main(String[] args) {
        List list = new ArrayList();
        //加的时候无所谓
        list.add("String");
        list.add(new Integer(2));
        list.add(new Boolean(false));
        //但是取的时候需要知道加进去的是什么类型,方便向下类型转换。
        String str = (String) list.get(0);
        Integer in = (Integer) list.get(1);
        Boolean bool = (Boolean) list.get(2);
        //我们改一下,编译通过,我的天哪,list.get(1)是Integer类型的!!
        //但是执行的时候,
        //ClassCastException: java.lang.Integer cannot be cast to java.lang.String
        String in1 = (String) list.get(1);
    }
}//编译时没有问题,但是执行时有问题,泛型可以解决这个问题

在JDK1.5中,你可以声明一个集合将接收/返回的对象的类型.

T并不是Java中的一个类,它代表的是一个类型的信息,

public class GenericFoo<T> {

    private T foo;

    public T getFoo() {
        return foo;
    }

    public void setFoo(T foo) {
        this.foo = foo;
    }

    public static void main(String[] args) {

        GenericFoo<Boolean> foo1 = new GenericFoo<Boolean>();
        GenericFoo<Integer> foo2 = new GenericFoo<Integer>();

        //只能传进去Boolean类型的
        foo1.setFoo(new Boolean(false));//其实可以自动装箱
        //只能传进去Integer类型的
        foo2.setFoo(new Integer(1));//其实可以自动装箱

        //返回的就是Boolean的,不用强制转换
        Boolean b = foo1.getFoo();
        //返回的就是Integer的,不用强制转换
        Integer in = foo2.getFoo();

        System.out.println(b);
        System.out.println(in);
    }

}

所谓泛型: 就是变量类型的参数化

以后使用集合要使用泛型!!

public class MapTest {
    public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();

        map.put("a", "aa");
        map.put("b", "bb");
        map.put("c", "cc");

        Set<String> set = map.keySet();
        for (Iterator<String> iter = set.iterator(); iter.hasNext(); ) {
            String key = iter.next();
            String value = map.get(key);
            System.out.println(key + ":" + value);
        }
        System.out.println("----------");

        Set<Map.Entry<String,String>> set2 = map.entrySet();
        for (Iterator<Map.Entry<String, String>> iter = set2.iterator(); iter.hasNext(); ) {
            Map.Entry<String, String> entry = iter.next();
            String key = entry.getKey();
            String value = entry.getValue();
            System.out.println(key + ":" + value);
        }
    }
}

如果使用泛型,只要代码在编译时没有出现警告,就不会遇到运行时ClassCastException。

限制泛型可用类型:

在定义泛型类别时,默认可以使用任何的类型来实例化泛型类型中的类型(GenericFoo<T>中的T可以指代任何类型),但是如果想要限制使用泛型类别时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字(即使是接口也是用extends)指定这个类型必须是继承某个类,或者实现某个接口。

/**
 * T必须是List接口的实现类,ArrayList可以,LinkedList可以,但是HashMap不可以
 */
public class ListGenericFoo<T extends List> 

当没有指定泛型继承的类型或接口时,默认使用T extends Object,所以默认情况下任何类型都可以作为参数传入

----------------

For-Each循环(增强for循环)

For-Each循环的加入简化了集合的遍历,其语法如下。

for(type element : array) {
  System.out.println(element);
}

type:集合或数组中每个元素的类型。

element:变量的名字,每个元素都赋给这个变量。

array:集合或数组的名字。

for(String name:names)
public class Test {
    public static void main(String[] args) {
        int[][] array = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
        for (int[] row : array) {
            for (int element : row) {
                System.out.println(element);
            }
        }
    }
}

当遍历集合或数组时,如果需要访问集合或数组的下标,那么最好使用旧式的方式来实现循环或遍历,而不要使用增强的 for 循环,因为它丢失了下标信息.

----------------

自动装箱/拆箱

Java中只有8个原生数据类型不是对象。

自动装箱/拆箱大大方便了基本类型数据和它们包装类的使用。
自动装箱: 基本类型自动转为包装类.(int->Integer)
自动拆箱: 包装类自动转为基本类型.(Integer->int)

List<Integer> list = new ArrayList<Integer>();
//Jdk4.0
list.add(new Integer(4));
//Jdk5.0
liat.add(4);

//Jdk4.0
Integer in = (Integer)list.get(i);
//Jdk5.0
Integer in = list.get(i);

Integer 类有一个缓存,它会缓存介于-128~127 之间的整数。

----------------------------

可变参数

可变参数使程序员可以声明一个接受可变数目参数(参数的个数会变化)的方法。注意,可变参数必须是方法声明中的最后一个参数.

//接收不同个数的参数
private static int sum(int... nums){
  int sum = 0;
  for (int num : nums) {
    sum += num;
  }
  return sum;
}

可变参数本质上就是一个数组,对于某个声明了可变参数的方法来说,我们既可以传递离散的值,也可以传递数组对象。但如果将方法中的参数定义为数组,那么只能传递数组对象而不能传递离散的值。
可变参数必须要作为方法参数的最后一个参数,即一个方法不可能具有两个或两个以上的可变参数。

private static int sum(String str, int... nums) {
}
private static int sum(int... nums,String str) {
}//错误

枚举

JDK1.5加入了一个全新类型的"类"-枚举类型。为此JDK1.5引入了一个新关键字enum. 我们可以这样来定义一个枚举类型。

public enum Color {
    Red,
    White,
    Blue
}
Color color = Color.Blue;

枚举类型还提供了两个有用的静态方法values()和valueOf(). 我们可以很方便地使用它们,例如

for (Color color : Color.values())
  System.out.println(color);

枚举(Enum): 我们所定义的每个枚举类型都继承自 java.lang.Enum 类,枚举中的每个成员默认都是 public static final 的。
而每个枚举的成员其实就是您定义的枚举类型的一個实例(Instance)。 换句话说,当定义了一个枚举类型后,在编译时刻就能确定该枚举类型有几个实例,分别是什么。在运行期间我们无法再使用该枚举类型创建新的实例了,这些实例在编译期间就已经完全确定下来了。

静态导入:
a)import static com.shengsiyuan.common.Common.Age;
b) import static com.shengsiyuan.common.Common.output;
表示导入 Common 类中的静态成员变量 AGE 以及静态方法 output。注意:使用 importstatic 时,要一直导入到类中的静态成员变量或静态方法。
Java 中,无论生成某个类的多少个对象,这些对象都会对应于同一个 Class 对象。