aCoder2013/blog

反射和泛型简析

aCoder2013 opened this issue · 0 comments

前言

泛型是在JDK1.5中才引入到Java的,
然而反射在JDK1.1就已经存在了,因此不可避免的出现了一些因为兼容性等原因,造成的一些容易令人疑惑的问题

正文

假如我们有一个Father类:

public class Father {
    public Father() {
        System.out.println("Father");
    }
}

子类Son继承Father类:

public class Son extends Father {
    public Song() {
        System.out.println("Son");
    }
}

再写一个测试类Main:

public class Main {
   Class<Son> sonClass = Son.class;
   Class<Father> fatherClass = sonClass.getSuperclass();//InCompatible Type
   Class<? super Son> fatherClass = sonClass.getSuperclass();//只能写成这种形式

}

但是这段代码却不能通过编译,编译器会告诉我们类型不兼容,这很令人疑惑,因为Java是单继承,这里很明确的Son的父类就是Father,问题就在于反射是在运行时加载类,而泛型是个编译时特性,在运行时会被擦除,
因此对于编译器来说,没有足够的信息去检查运行时类型是否正确,只能够根据方法的返回值类型去检查,比如:Class.newInstance()的返回值是T,因此就能够根据泛型的信息直接得到确切的类型,而 Object father = fatherClass.newInstance();
却只能得到Object类型

Class<Integer> integerClass  = Integer.class;
Integer i = integerClass.newInstance();
 public T newInstance()throws InstantiationException, IllegalAccessException {
		...			
 }

而getSupperclass()的方法签名为 public native Class<? super T> getSuperclass();,这时候编译器只知道返回值是T的父类但不知道确切的类型,因此当你用Class的时候会得到一个编译错误.

Flag Counter