反射和泛型简析

- 1 min

前言

泛型是在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的时候会得到一个编译错误.

comments powered by Disqus
rss facebook twitter github youtube mail spotify lastfm instagram linkedin google google-plus pinterest medium vimeo stackoverflow reddit quora quora