上篇主要将<D>和<D extends List>这类范型变量定义
而<>中如果是具体的某个类或者是?之类的就不是范型变量定义了,比如<String[]>,<String>,<? extends List>.比方说以下代码
就ClassB<String, String[], ? super List, ClassC<String>>来说,对应的是ParameterizedType,这时候没有对范型变量的定义了,而是把那些范型定义中的大写字母实例化成了具体的Type。TypeVariable<D>和ParameterizedType就像类和实例间的关系。
如果只是单独的ClassB,没有任何<>,那么它就对应普通的Class类,普通类也是Type的一种。
当我们调用
Class.getGenericSuperClass
Class.getGenericInterfaces
Method.getGenericExceptionTypes
Method.getGenericParameterTypes
Method.getGenericReturnType
Constructor.getGenericExceptionTypes
Constructor.getGenericParameterTypes
都会返回Type对象或者Type数组,这些Type有可能ParameterizedType, Class, GenericArrayType中的一种,需要进行运行时类型检查,然后在强制转型做处理。这里是WildcardType可能性不大,毕竟无论是超类,接口,方法入参,返回值和异常都不可能用?通配符这种WildcardType.
如果使用ClassA.getGenericSuperClass()方法返回的type,检查后就会转型成ParameterizedType。然后可以通过ParameterizedType.getActualTypeArguments再得到一个Type数组,这些type数组对应的就是String, String[], ? super List, ClassC<String>,四种范型。
进一步,ClassB中的四个范型变量的实例,分别是
String,对应Class,
String[],对应GenericArrayType
? extends List,对应WildcardType
ClassC<String>,又对应ParameterizeType
这些都是要通过运行时类型检查来判断他们到底是什么样的Type
拿到Class,那么该干嘛干嘛,不用多说
当我们拿到的是GenericArrayType,那么对应的就是一个数组,可以通过getGenericComponentType方法拿到实际定义数组的类型,返回的Type可能是Class,ParameterizeType继续做检查然后再转型吧,当然也是有肯能是GenericArrayType,比如二维数组。
当我们拿到的是WildcardType,可以通过getLowerBounds和getSuperBounds来获取?对应的上下边界Type,这里拿到的Type也是不确定需要做检查的,可能的类型包括Class,ParameterizeType, 或者GenericArrayType,WildcardType应该不会出现。
当我们拿到的是ParameterizeType,那么可以通过getActualTypeArguments进一步获取ClassC<Stirng>中的参数String.class(其实还是Type经过检查获取的),也可以通过getRawType拿到ClassC.class
总之这么一层一层的下去,不停的通过各种方法获取Type和Type数组,然后判定是那一种Type,再继续处理。但不太可能拿到的Type是TypeVariable<D>了。所以对于整个范型模型的理解层次,我觉得
最高自然是Type,
接下去是GenericDeclaration和TypeVariable<D>
最下层是ParameterizedType,Class,GenericArrayType,WildcardType
实际上可能ParameterizedType,Class比后两者略高
而<>中如果是具体的某个类或者是?之类的就不是范型变量定义了,比如<String[]>,<String>,<? extends List>.比方说以下代码
public class ClassA extends ClassB<String, String[], ? extends List, ClassC<String>> {
}
就ClassB<String, String[], ? super List, ClassC<String>>来说,对应的是ParameterizedType,这时候没有对范型变量的定义了,而是把那些范型定义中的大写字母实例化成了具体的Type。TypeVariable<D>和ParameterizedType就像类和实例间的关系。
如果只是单独的ClassB,没有任何<>,那么它就对应普通的Class类,普通类也是Type的一种。
当我们调用
Class.getGenericSuperClass
Class.getGenericInterfaces
Method.getGenericExceptionTypes
Method.getGenericParameterTypes
Method.getGenericReturnType
Constructor.getGenericExceptionTypes
Constructor.getGenericParameterTypes
都会返回Type对象或者Type数组,这些Type有可能ParameterizedType, Class, GenericArrayType中的一种,需要进行运行时类型检查,然后在强制转型做处理。这里是WildcardType可能性不大,毕竟无论是超类,接口,方法入参,返回值和异常都不可能用?通配符这种WildcardType.
如果使用ClassA.getGenericSuperClass()方法返回的type,检查后就会转型成ParameterizedType。然后可以通过ParameterizedType.getActualTypeArguments再得到一个Type数组,这些type数组对应的就是String, String[], ? super List, ClassC<String>,四种范型。
进一步,ClassB中的四个范型变量的实例,分别是
String,对应Class,
String[],对应GenericArrayType
? extends List,对应WildcardType
ClassC<String>,又对应ParameterizeType
这些都是要通过运行时类型检查来判断他们到底是什么样的Type
拿到Class,那么该干嘛干嘛,不用多说
当我们拿到的是GenericArrayType,那么对应的就是一个数组,可以通过getGenericComponentType方法拿到实际定义数组的类型,返回的Type可能是Class,ParameterizeType继续做检查然后再转型吧,当然也是有肯能是GenericArrayType,比如二维数组。
当我们拿到的是WildcardType,可以通过getLowerBounds和getSuperBounds来获取?对应的上下边界Type,这里拿到的Type也是不确定需要做检查的,可能的类型包括Class,ParameterizeType, 或者GenericArrayType,WildcardType应该不会出现。
当我们拿到的是ParameterizeType,那么可以通过getActualTypeArguments进一步获取ClassC<Stirng>中的参数String.class(其实还是Type经过检查获取的),也可以通过getRawType拿到ClassC.class
总之这么一层一层的下去,不停的通过各种方法获取Type和Type数组,然后判定是那一种Type,再继续处理。但不太可能拿到的Type是TypeVariable<D>了。所以对于整个范型模型的理解层次,我觉得
最高自然是Type,
接下去是GenericDeclaration和TypeVariable<D>
最下层是ParameterizedType,Class,GenericArrayType,WildcardType
实际上可能ParameterizedType,Class比后两者略高