1. Java中Generics泛型
class="java">
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的子类,但不确定是什么类的实例,编译器不让您加入信息,理由是,如果可以加入信息的話,那么您就得記得取回的实例是什么类型,然后转换为原來的类型方可进行操作,这就失去了使用泛型的意义。