[转] 范型是这样的-1

 
大家都说Java范型是编译器层面的实现,运行时拿不到范型类。就这句话,我的理解就是,通过对象实例,你是拿不到其范型相关信息,而记录在字节码里的,也就是类上的,方法上的,类变量上的还是可以拿到的。比如某个类中的代码 
Java代码  收藏代码
  1. //这里Alist的超类限制了是只能放String的范型  
  2. //这个范型信息可以通过Alist.class来获取  
  3. public class AList extends ArrayList<String> {  
  4.   
  5.     public void Test() {  
  6.         //这个list实例的范型定义应该是只能放String  
  7.         //但这个信息是仅仅依靠list这个实例引用是取不到的  
  8.         List<String> list = new ArrayList<String>()  
  9.     }  
  10.   
  11. }  


java范型的根对象是java.lang.reflect.Type接口该接口没有任何方法,仅仅是一个标志性的接口,所有的范型信息(也就是<>中定义的东西)都是可以上溯到该接口。 


该接口下有四类子接口和一实现类,实现类就是Class类,而接口包括: 
GenericArrayType, ParameterizedType, TypeVariable<D>, WildcardType 
妈的,这几个名字可够拗口的。其中TypeVariable<D>和其他三种接口类型有一定的明显区别,虽然他们都是用来定义<>中的东东。 


说到TypeVariable<D>就不得不提起java范型中另一个比较重要的接口对象,java.lang.reflect.GenericDeclaration接口对象。该接口用来定义哪些对象上是可以声明范型变量,所谓范型变量就是<E extends List>或者<E>, 也就是TypeVariable<D>这个接口的对应的对象,TypeVariable<D>中的D是extends GenericDeclaration的,用来通过范型变量反向获取拥有这个变量的GenericDeclaration 

目前实现GenericDeclaration接口的类包括Class, Method, Constructor,也就是只能在这几种对象上进行范型变量的声明。GenericDeclaration的接口方法getTypeParameters用来逐个获取该GenericDeclaration的范型变量声明。 
比如: 
Java代码  收藏代码
  1. public class ClassA <K extends List & Serializable, V> {  
  2.   
  3. }  


类ClassA上就有两个TypeVariable<D>可以通过ClassA.class.getTypeParameters()[0]来获取第一个范型变量"K extends List"的信息。从而更进一步拿到变量名字,变量上界,变量所在的GenericDeclaration对象。 

Java代码  收藏代码
  1. //获取范型变量定义  
  2. TypeVariable t = ClassA.class.getTypeParameters()[0];  
  3. t.getName();//获取变量名字,返回K  
  4. t.getGenericDeclaration();//获取变量被定义在什么GenericDeclaration上,这里返回ClassA.class  
  5. t.getBounds()[0];//变量上边界数组,这里返回List.class  
  6. t.getBounds()[1];//变量上边界数组,这里返回Serializable.class  
  7.   
  8. //当然可以获取第二个变量定义  
  9. t = ClassA.class.getTypeParameters()[1];  
  10. t.getName();//返回V  
  11. t.getGenericDeclaration();//获取变量被定义在什么GenericDeclaration上,这里返回ClassA.class  
  12. t.getBounds()[0];//变量上边界数组,这里返回Object.class,并且上边界只有一个  
posted @ 2012-08-12 08:54  书山瞌睡虫  阅读(233)  评论(0编辑  收藏  举报