1、JDK5.0中的新特性包括:
① 泛型(Generics)
② 增强的for循环(Enhanced for loop)
③ 自动装箱/自动拆箱(Autoboxing/unboxing)
④ 类型安全的枚举(Type safe enums)
⑤ 静态导入(Static import)
⑥ 可变参数(var args)
下面介绍泛型相关的使用:
2、泛型:
变量类型的参数化。通过引入泛型,将获得编译时类型的安全和运行时更小的跑出ClassCastExceptions异常。
2.1、自定义泛型实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class MyGenerics<T1,T2> {
private T1 param1; private T2 param2; public T1 getParam1() { return param1; } public void setParam1(T1 param1) { this.param1 = param1; } public T2 getParam2() { return param2; } public void setParam2(T2 param2) { this.param2 = param2; } }
|
使用自定义的泛型:
1 2 3 4 5 6
| public static void main(String[] args) { MyGenerics<Integer, String> myGenerics = new MyGenerics<Integer, String>(); myGenerics.setParam1(1); myGenerics.setParam2("abc"); }
|
2.2、自定义泛型数组:
1 2 3 4 5 6 7 8 9 10 11
| public class MyGenerics2<T> {
private T[] param1; public T[] getParam1() { return param1; } public void setParam1(T[] param1) { this.param1 = param1; } }
|
不能使用new关键字创建T类型的对象,而应该传递一个具体的参数类型,如下面的将编译不通过:
1
| MyGenerics<Integer, String> myGenerics = new MyGenerics<T1, T2>();
|
2.3、把普通类型转换成泛型:
1 2 3
| public MyGenerics2(){ param1 = (T[])new Object[10]; }
|
2.4、泛型的泛型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class MyGenerics3<T1,T2> {
private MyGenerics<T1,T2> myGenerics; public MyGenerics<T1, T2> getMyGenerics() { return myGenerics; } public void setMyGenerics(MyGenerics<T1, T2> myGenerics) { this.myGenerics = myGenerics; } public static void main(String[] args) { MyGenerics3<Integer, String> myGenerics3 = new MyGenerics3<Integer, String>(); myGenerics3.setMyGenerics(new MyGenerics<Integer, String>()); } }
|
2.5、泛型在HashMap遍历中的使用:
详细参考:
Map映射集合实现类HashMap的介绍和迭代遍历方法
Map映射集合实现类HashMap的介绍和迭代遍历方法
遍历HashMap有 种方法,其中使用Entry遍历如下:
1 2 3 4 5 6 7 8
| Set<Map.Entry<String, String>> set1 = map.entrySet(); for(Iterator<Map.Entry<String, String>> iter = set1.iterator(); iter.hasNext();){ Map.Entry<String, String> entry = iter.next(); String key = entry.getKey(); String value = entry.getValue(); System.out.println(key + ":" \+ value); }
|
2.6、使用泛型的好处:
如果使用了泛型,只要代码在编译时没有出现警告信息,就不会遇到运行时的ClassCastException异常。
2.7、限制使用泛型的类型:
在定义泛型类型时,预设的可以使用任何类型来实例化泛型类型中的类型。如果想要限制泛型类型时,使其只能使用某个特定类型或者其子类型才能实例化该类型时,可以通过:
2.7.1、定义类时限定类型:
使用extends关键字指定类型:
不管是类还是接口,都使用extends:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| extends List<String>
public class MyGenerics4<T extends List<String>> {
private T[] param1; public T[] getParam1() { return param1; } public void setParam1(T[] param1) { this.param1 = param1; } }
|
注意:
当没有指定泛型继承的类型或者接口时,默认使用:
T extends Object
所以默认情况下任何类型都可以作为参数传入。
ArrayList
等价于:
ArrayList list = new ArrayList();
2.7.2、在使用时限定类型:
类型的通配声明:
可以使用’?’通配字元,并使用extends关键字限定持有者的类型。
声明一个类型时进行限定:
下面使用之前编写的MyGenerics类进行说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| public static void main(String[] args) { MyGenerics<? extends Object, ? extends List<String>> myGenerics = null; myGenerics = new MyGenerics<String, ArrayList<String>>();
MyGenerics3<? extends Object, ? extends List<String>> myGenerics3 = null; myGenerics3 = new MyGenerics3<Object, List<String>>(); myGenerics3.setMyGenerics(null); }
|
1
| MyGenerics3<?, ?> myGenerics3 = null;
|
等价于:
1
| MyGenerics3<? extends Object, ? extends Object> myGenerics5 = null;
|
2.8、泛型的继承:
父类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class ParentGenerics<T1, T2> {
private T1 param1; private T2 param2; public T1 getParam1() { return param1; } public void setParam1(T1 param1) { this.param1 = param1; } public T2 getParam2() { return param2; } public void setParam2(T2 param2) { this.param2 = param2; } }
|
子类:
1 2 3 4 5 6 7 8 9 10 11 12
| public class ChildGenerics<T1, T2, T3> extends ParentGenerics<T1, T2> {
private T3 param3; public T3 getParam3() { return param3; } public void setParam3(T3 param3) { this.param3 = param3; } }
|
2.9、泛型接口的实现:
接口:
1 2 3 4 5 6
| public interface GenericsInterface<T1, T2> {
public void setParam1(T1 t1); public void setParam2(T2 t2); }
|
实现类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class GenericsImpl<T1, T2, T3> implements GenericsInterface<T1, T2> {
private T1 t1; private T2 t2; @Override public void setParam1(T1 t1) { this.t1 = t1; } @Override public void setParam2(T2 t2) { this.t2 = t2; } }
|