java 泛型 擦除


示例1:
Class class1= new ArrayList<String>().getClass();

Class class2=new ArrayList<Integer>().getClass();

System. out.println(class1==class2);

输出:true

解释:
ArrayList<String>和ArrayList<Integer>在运行时,事实上是相同的类型。这两种形式都被他们擦除成它们的“原生”类型,即ArrayList。
 
 
 
示例2:
Class class3= new HashMap<String, Long>().getClass();
Class class4=new HashMap<Double, Exception>().getClass();
System. out.println(class3==class4);
System. out.println(Arrays.toString(class3.getTypeParameters()));
System. out.println(Arrays.toString(class4.getTypeParameters()));

输出:

true
[K, V]
[K, V]
 
解释:
在泛型代码内部,无法获得任何有关泛型参数类型的信息。
 
 
 
示例3:
 1 class HasF{
 2 
 3         public void f(){
 4               System. out.println("Hasf obj.f()..." );
 5        }
 6 
 7 }
 8 
 9  
10 
11 class Manipulator<T extends HasF>{
12         private T obj ;
13 
14         public Manipulator(T x){
15                obj=x;
16        }
17 
18         public void manipulate(){
19                obj.f();
20        }
21 }
22 
23  
24 
25 public class ErasedType {
26 
27         public static void main(String[] args){
28               HasF hasF= new HasF();
29               Manipulator<HasF> manipulator= new Manipulator<HasF>(hasF);
30               manipulator.manipulate();
31        }
32 }

解释:

如果没有extends HasF,将不能调用T obj 的 f() 方法。
泛型参数类型将擦除到它的第一个边界,编译器实际上会把 参数类型T 替换为它的非泛型上届,如:<T extends HasF>被擦除为HasF,<T>被擦除为Object。
 
 
示例4
 1 class Erased<T>{
 2        T obj;
 3 
 4         public Erased(){
 5                obj= new T();报错
 6        }
 7       
 8         public void f(Object object){
 9                boolean result= object instanceof T ;//!!报错
10        }
11 }

运行时,擦书在方法或类内部移除了有关实际类型的信息。

小结:

擦除减少了泛型的泛化性。java这样设计泛型主要是为了兼容之前没有泛型时候的java语言(迁移兼容性)。
 
 
 
 
 
 
posted @ 2013-02-22 11:12  windlaughing  阅读(367)  评论(0编辑  收藏  举报