[转] 范型是这样的-1
大家都说Java范型是编译器层面的实现,运行时拿不到范型类。就这句话,我的理解就是,通过对象实例,你是拿不到其范型相关信息,而记录在字节码里的,也就是类上的,方法上的,类变量上的还是可以拿到的。比如某个类中的代码
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的范型变量声明。
比如:
类ClassA上就有两个TypeVariable<D>可以通过ClassA.class.getTypeParameters()[0]来获取第一个范型变量"K extends List"的信息。从而更进一步拿到变量名字,变量上界,变量所在的GenericDeclaration对象。
- //这里Alist的超类限制了是只能放String的范型
- //这个范型信息可以通过Alist.class来获取
- public class AList extends ArrayList<String> {
- public void Test() {
- //这个list实例的范型定义应该是只能放String
- //但这个信息是仅仅依靠list这个实例引用是取不到的
- List<String> list = new ArrayList<String>()
- }
- }
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的范型变量声明。
比如:
- public class ClassA <K extends List & Serializable, V> {
- }
类ClassA上就有两个TypeVariable<D>可以通过ClassA.class.getTypeParameters()[0]来获取第一个范型变量"K extends List"的信息。从而更进一步拿到变量名字,变量上界,变量所在的GenericDeclaration对象。
- //获取范型变量定义
- TypeVariable t = ClassA.class.getTypeParameters()[0];
- t.getName();//获取变量名字,返回K
- t.getGenericDeclaration();//获取变量被定义在什么GenericDeclaration上,这里返回ClassA.class
- t.getBounds()[0];//变量上边界数组,这里返回List.class
- t.getBounds()[1];//变量上边界数组,这里返回Serializable.class
- //当然可以获取第二个变量定义
- t = ClassA.class.getTypeParameters()[1];
- t.getName();//返回V
- t.getGenericDeclaration();//获取变量被定义在什么GenericDeclaration上,这里返回ClassA.class
- t.getBounds()[0];//变量上边界数组,这里返回Object.class,并且上边界只有一个