Generics泛型是 JDK 5 中引入的一个新特性, 泛型提供了编译时类型安全检测机制,该机制允许程序员在编译时检测到非法的类型。 泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。 import java.util.ArrayList; import java.util.List; 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); String b = (String)list.get(2); } } 运行结果: Exception in thread "main" java.lang.ClassCastException: java.lang.Boolean cannot be cast to java.lang.String at org07.ArrayListTest.main(ArrayListTest.java:18)
2. 自定义泛型
自定义泛型,可以定义多个泛型Generic<T1, T2>,用set和get方法实现。 public class Generic<T1, T2>{ private T1 foo1; private T2 foo2; public T1 getFoo1(){ return foo1; } public void setFoo1(T1 foo1){ this.foo1 = foo1; } public T2 getFoo2(){ return foo2; } public void setFoo2(T2 foo2){ this.foo2 = foo2; } public static void main(String[] args){ Generic<Integer, Boolean> foo = new Generic<Integer, Boolean>(); foo.setFoo1(new Integer(-20)); foo.setFoo2(new Boolean(false)); System.out.println(foo.getFoo1()); System.out.println(foo.getFoo2()); } } 运行结果: -20 false 泛型数组的存取 public class Generic2<T>{ private T[] fooArray; public T[] getFooArray(){ return fooArray; } public void setFooArray(T[] fooArray){ this.fooArray = fooArray; } public static void main(String[] args){ Generic2<String> foo = new Generic2<String>(); String[] str1 = {"hello", "world", "welcome"}; String[] str2 = null; foo.setFooArray(str1); str2 = foo.getFooArray(); for(int i = 0; i < str2.length; i++){ System.out.println(str2[i]); } } } 运行结果: hello world welcome
3. 泛型的泛型
public class WrapperFoo<T>{ private GenericFoo3<T> foo; public GenericFoo3<T> getFoo(){ return foo; } public void setFoo(GenericFoo3<T> foo){ this.foo = foo; } public static void main(String[] args){ GenericFoo3<Integer> foo = new GenericFoo3<Integer>(); foo.setFoo(new Integer(-10)); WrapperFoo<Integer> wrapper = new WrapperFoo<Integer>(); wrapper.setFoo(foo); GenericFoo3<Integer> g = wrapper.getFoo(); System.out.println(g.getFoo()); } } class GenericFoo3<T>{ private T foo; public T getFoo(){ return foo; } public void setFoo(T foo){ this.foo = foo; } } 运行结果: -10
4. 泛型上下边界
限制泛型的类型用extends关键字。ListGenericFoo<T extends List> 当我们没有指定泛型的类型或接口时,默认使用T extends Object,任何类型都可以作为参数传入。 import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; public class ListGenericFoo<T extends List>{ private T[] fooArray; public T[] getFooArray(){ return fooArray; } public void setFooArray(T[] fooArray){ this.fooArray = fooArray; } public static void main(String[] args){ ListGenericFoo<LinkedList> foo1 = new ListGenericFoo<LinkedList>(); ListGenericFoo<ArrayList> foo2 = new ListGenericFoo<ArrayList>(); LinkedList[] linkedList = new LinkedList[10]; foo1.setFooArray(linkedList); ArrayList[] arrayList = new ArrayList[10]; foo2.setFooArray(arrayList); // ListGenericFoo<HashMap> foo3 = new ListGenericFoo<HashMap>(); } } GenericTest<? extends List> 在声明引用的时候才对泛型进行限定。 GenericTest<? super List> 在声明引用的时候才对泛型进行限定。(在List之上的泛型) import java.util.ArrayList; import java.util.LinkedList; import java.util.List; public class GenericTest<T>{ private T foo; public T getFoo(){ return foo; } public void setFoo(T foo){ this.foo = foo; } public static void main(String[] args){ GenericTest<? extends List> ge = null; ge = new GenericTest<ArrayList>(); ge = new GenericTest<LinkedList>(); // ge = new GenericTest<HashMap>(); GenericTest<? super List> ge2 = null; ge2 = new GenericTest<Object>(); GenericTest<String> ge3 = new GenericTest<String>(); ge3.setFoo("hello world"); GenericTest<?> ge4 = ge3; System.out.println(ge4.getFoo()); ge4.setFoo(null); System.out.println(ge4.getFoo()); // ge4.setFoo("welcome"); } } 运行结果: hello world null ge4.setFoo("welcome");是错误的。因为需要强制类型转换。不符合泛型定义。 使用<?>或是<? extends SomeClass>的声明方式,意味著您只能通过该名称來取得所参考实例的信息,或者是移除某些信息,但不能增加它的信息,因为只知道当中放置的是SomeClass的子类,但不确定是什么类的实例,编译器不让您加入信息,理由是,如果可以加入信息的話,那么您就得記得取回的实例是什么类型,然后转换为原來的类型方可进行操作,这就失去了使用泛型的意义。