Type、TypeVariable、ParameterizedType、GenericArrayType、WildcardType、Class
1.官方文档
2.简介
2.1 继承关系
2.2 作用
Type |
反射api中,用来描述类型的公共接口. Class是它的实现类 : 用在描述非泛型类型. 其它的都是它的子接口 : 用在描述泛型中的类型. |
Class | 用于描述正在进行中的 [ 类、接口 ] 的信息。 |
TypeVariable | 用类模板参数声明成员时的模板参数类型,如 class List<T>{ T member;} 中的member 的类型 T |
ParameterizedType | 带泛型参数的类型。例如 Collection<String> |
GenericArrayType | TypeVariable和 ParameterizedType 声明的泛型数组类型。 如 List<T>[] , T[] |
WildcardType | 泛型通配符表达式所表达的类型,例如List<?>中的?,List<? extends Number>里的? extends Number 和List<? super Integer>的? super Integer |
3.TypeVariable
用类模板参数声明成员时的模板参数类型,如 class List<T>{ T member;}
中的member 的类型 T
3.1 api
String getName() | 返回 泛型参数的名字,比如:T |
Type[] getBounds() | 返回此类型参数的上界列表,如果没有上界则放回Object |
D getGenericDeclaration() | 返回类型变量声明载体类对象 |
AnnotatedType[] getAnnotatedBounds() |
Returns an array of AnnotatedType objects that represent the use of types to denote the upper bounds of the type parameter represented by this TypeVariable. |
3.2 示例
1 @Retention(RetentionPolicy.RUNTIME) 2 @Target(value = {ANNOTATION_TYPE, CONSTRUCTOR, FIELD, METHOD, PACKAGE, PARAMETER, TYPE, TYPE_PARAMETER, TYPE_USE}) 3 public @interface Custom { } 4 class UUU <T extends String,V extends @Custom Number & Serializable>{ 5 public T t; 6 public V v; 7 8 public T[] tArray; 9 public List<T>[] listTArray; 10 11 public List<T> list = new ArrayList<>(); 12 public Map<Float,T> map= new HashMap<>(); 13 public Map<? super String, ? extends Number> mapWithWildcard; 14 public UUU <String,Number> uuu; 15 16 public int values(T ... ts){ return ts.length; } 17 } 18 @Test @SmallTest 19 public void test_typeVariable(){ 20 21 UUU<String,Float> obj = new UUU(); 22 //Type type0 = obj.getClass().getGenericType(); 错误,只有Field才能得到type,而class不能得到type 23 24 Type sp = obj.getClass().getGenericSuperclass(); 25 Class<?> clazz = obj.getClass(); 26 try { 27 printTypeVariable(clazz.getField("t").getGenericType()); 28 printTypeVariable(clazz.getField("v").getGenericType()); 29 printTypeVariable(clazz.getField("list").getGenericType()); 30 printTypeVariable(clazz.getField("map").getGenericType()); 31 printTypeVariable(clazz.getField("tArray").getGenericType()); 32 printTypeVariable(clazz.getField("listTArray").getGenericType()); 33 printTypeVariable(clazz.getField("mapWithWildcard").getGenericType()); 34 } catch (NoSuchFieldException e) { 35 e.printStackTrace(); 36 } 37 } 38 private void printTypeVariable(Type t){ 39 System.out.println("------------------------------") ; 40 if (!(t instanceof TypeVariable)){ 41 System.out.println(t.getTypeName() + " is not TypeVariable"); 42 return; 43 } 44 TypeVariable type = (TypeVariable) t; 45 String typeName = type.getTypeName(); 46 String name = type.getName(); 47 Type[] bounds = type.getBounds(); 48 GenericDeclaration d= type.getGenericDeclaration(); 49 50 System.out.println("name = " + name) ; 51 System.out.println("typeName = " + typeName) ; 52 System.out.println("bounds[] = " + Arrays.asList(bounds)) ; 53 System.out.println("declaration = " + d) ; 54 }
只有第5的t 和第6 行的v 对应的类型是 TypeVariable ,结果:
1 ------------------------------ 2 name = T 3 typeName = T 4 bounds[] = [class java.lang.String] 5 declaration = class com.example.sjjg.utest.MockitoJava$UUU 6 ------------------------------ 7 name = V 8 typeName = V 9 bounds[] = [class java.lang.Number, interface java.io.Serializable] 10 declaration = class com.example.sjjg.utest.MockitoJava$UUU 11 ------------------------------ 12 java.util.List<T> is not TypeVariable 13 ------------------------------ 14 java.util.Map<java.lang.Float, T> is not TypeVariable 15 ------------------------------ 16 T[] is not TypeVariable 17 ------------------------------ 18 java.util.List<T>[] is not TypeVariable 19 ------------------------------ 20 java.util.Map<? super java.lang.String, ? extends java.lang.Number> is not TypeVariable
4.ParameterizedType
带泛型参数的类型。例如 Collection<String>
4.1 api
Type getRawType() |
返回源类型,如 Collection<String> 中的 Collection
|
Type getOwnerType() |
返回源类型的外部类型,没有则返回null,如 Collection的外部类型为null
|
Type[] getActualTypeArguments() |
返回泛型参数组,如Map<String,Float>则返回 [String,Float]
|
4.2 示例
1 @Retention(RetentionPolicy.RUNTIME) 2 @Target(value = {ANNOTATION_TYPE, CONSTRUCTOR, FIELD, METHOD, PACKAGE, PARAMETER, TYPE, TYPE_PARAMETER, TYPE_USE}) 3 public @interface Custom { } 4 class UUU <T extends String,V extends @Custom Number & Serializable>{ 5 public T t; 6 public V v; 7 8 public T[] tArray; 9 public List<T>[] listTArray; 10 11 public List<T> list = new ArrayList<>(); 12 public Map<Float,T> map= new HashMap<>(); 13 public Map<? super String, ? extends Number> mapWithWildcard; 14 public UUU <String,Number> uuu; 15 16 public int values(T ... ts){ return ts.length; } 17 } 18 @Test @SmallTest 19 public void test_parameterizedType(){ 20 UUU<String,Float> obj = new UUU(); 21 //Type type0 = obj.getClass().getGenericType(); //错误,只有Field才能得到type,而class不能得到type 22 Class<?> clazz = obj.getClass(); 23 try { 24 printParameterizedType(clazz.getField("list").getGenericType()); 25 printParameterizedType(clazz.getField("map").getGenericType()); 26 printParameterizedType(clazz.getField("mapWithWildcard").getGenericType()); 27 printParameterizedType(clazz.getField("uuu").getGenericType()); 28 } catch (NoSuchFieldException e) { 29 e.printStackTrace(); 30 } 31 } 32 private void printParameterizedType(Type t){ 33 System.out.println("------------------------------"); 34 if (!(t instanceof ParameterizedType)){ 35 System.out.println(t.getTypeName() + " is not ParameterizedType"); 36 return; 37 } 38 ParameterizedType type = (ParameterizedType) t; 39 Type raw = type.getRawType(); 40 Type owner = type.getOwnerType(); 41 Type[] actual = type.getActualTypeArguments(); 42 43 System.out.println("raw = " + raw.getTypeName()); 44 System.out.println("owner = " + (owner != null ? owner.getTypeName() : "null")); 45 46 //print ActualTypes 47 if (actual.length > 0){ 48 for (int i = 0 ; i < actual.length; ++i){ 49 System.out.println("actual[ " + i + " ] = " + actual[i].getTypeName()); 50 } 51 } 52 }
代码中第11 12 13 14 行分别声明了4个成员,它们的类型在反射后的 type 都是 ParameterizedType,结果为:
1 ------------------------------ 2 raw = java.util.List 3 owner = null 4 actual[ 0 ] = T 5 ------------------------------ 6 raw = java.util.Map 7 owner = null 8 actual[ 0 ] = java.lang.Float 9 actual[ 1 ] = T 10 ------------------------------ 11 raw = java.util.Map 12 owner = null 13 actual[ 0 ] = ? super java.lang.String 14 actual[ 1 ] = ? extends java.lang.Number 15 ------------------------------ 16 raw = com.example.sjjg.utest.MockitoJava$UUU 17 owner = com.example.sjjg.utest.MockitoJava 18 actual[ 0 ] = java.lang.String 19 actual[ 1 ] = java.lang.Number
5.GenericArrayType
TypeVariable和 ParameterizedType 声明的泛型数组类型。 如 List<T>[] , T[]
5.1 api
Type getGenericComponentType() |
Returns a
Type object representing the component type of this array. |
5.2 示例
1 @Retention(RetentionPolicy.RUNTIME) 2 @Target(value = {ANNOTATION_TYPE, CONSTRUCTOR, FIELD, METHOD, PACKAGE, PARAMETER, TYPE, TYPE_PARAMETER, TYPE_USE}) 3 public @interface Custom { } 4 class UUU <T,V extends @Custom Number & Serializable>{ 5 public Number number; 6 public T t; 7 public V v; 8 9 public T[] tArray; 10 public List<T>[] listTArray; 11 12 public List<T> list = new ArrayList<>(); 13 public Map<Float,T> map= new HashMap<>(); 14 public Map<? super String, ? extends Number> mapWithWildcard; 15 public UUU <String,Float> uuu; 16 17 public int values(T ... ts){ return ts.length; } 18 } 19 @Test @SmallTest 20 public void test_GenericArrayType(){ 21 UUU<String,Float> obj = new UUU(); 22 //Type type0 = obj.getClass().getGenericType(); 错误,只有Field才能得到type,而class不能得到type 23 24 Type sp = obj.getClass().getGenericSuperclass(); 25 Class<?> clazz = obj.getClass(); 26 try { 27 printGenericArrayType(clazz.getField("tArray").getGenericType()); 28 printGenericArrayType(clazz.getField("listTArray").getGenericType()); 29 } catch (NoSuchFieldException e) { 30 e.printStackTrace(); 31 } 32 } 33 private void printGenericArrayType(Type t){ 34 System.out.println("------------------------------"); 35 if (!(t instanceof GenericArrayType)){ 36 System.out.println(t.getTypeName() + " is not GenericArrayType"); 37 return; 38 } 39 GenericArrayType type = (GenericArrayType) t; 40 String typeName = type.getTypeName(); 41 Type componentType = type.getGenericComponentType(); 42 43 System.out.println("typeName = " + typeName); 44 System.out.println("componentType = " + componentType.getTypeName()); 45 }
上述代码中的第9,10行,成员的类型就是GenericArrayType,结果
1 ------------------------------ 2 typeName = T[] 3 componentType = T 4 ------------------------------ 5 typeName = java.util.List<T>[] 6 componentType = java.util.List<T>
6.WildcardType
泛型通配符 [ ? 表达式 ] 所表达的类型,例如List<?>中的?,List<? extends Number>里的? extends Number 和List<? super Integer>的? super Integer,而
class UUU <T extends String,V extends @Custom Number & Serializable> 中的T extends String 和 V extends @Custom Number & Serializable不是.它们没有问号.
6.1 api
Type[] getLowerBounds() |
返回泛型的下界,如List<? super Integer>中的 Integer,没有下界时默认为null
|
Type[] getUpperBounds() |
返回泛型的上界,如List<? extends Number>中的 Number,没有上界时默认为Object
|
6.2 示例
1 @Retention(RetentionPolicy.RUNTIME) 2 @Target(value = {ANNOTATION_TYPE, CONSTRUCTOR, FIELD, METHOD, PACKAGE, PARAMETER, TYPE, TYPE_PARAMETER, TYPE_USE}) 3 public @interface Custom { } 4 class UUU <T extends String,V extends @Custom Number & Serializable>{ 5 public T t; 6 public V v; 7 8 public T[] tArray; 9 public List<T>[] listTArray; 10 11 public List<T> list = new ArrayList<>(); 12 public Map<Float,T> map= new HashMap<>(); 13 public Map<? super String, ? extends Number> mapWithWildcard; 14 public UUU <String,Number> uuu; 15 16 public int values(T ... ts){ return ts.length; } 17 } 18 public void test_WildcardType() { 19 UUU<String, Float> obj = new UUU(); 20 //Type type0 = obj.getClass().getGenericType(); 错误,只有Field才能得到type,而class不能得到type 21 22 Type sp = obj.getClass().getGenericSuperclass(); 23 Class<?> clazz = obj.getClass(); 24 try { 25 printWildcardType(clazz.getField("uuu").getGenericType()); 26 printWildcardType(clazz.getField("mapWithWildcard").getGenericType()); 27 } catch (NoSuchFieldException e) { 28 e.printStackTrace(); 29 } 30 } 31 private void printWildcardType(Type t){ 32 System.out.println("------------------------------"); 33 if (!(t instanceof ParameterizedType)){ 34 System.out.println(t.getTypeName() + " is not WildcardType"); 35 return; 36 } 37 ParameterizedType type = (ParameterizedType) t; 38 String typeName = type.getTypeName(); 39 Type[] actual = type.getActualTypeArguments(); 40 41 System.out.println("typeName = " + typeName); 42 43 if (actual.length > 0){ 44 for (int i = 0 ; i < actual.length; ++i){ 45 Type at = actual[i]; 46 System.out.println("actual[ " + i + " ] = " + at.getTypeName()); 47 if (!(at instanceof WildcardType)){ 48 System.out.println(" it is not WildcardType"); 49 continue; 50 } 51 WildcardType wildcardType = (WildcardType) at; 52 Type[] lower = wildcardType.getLowerBounds(); 53 Type[] upper = wildcardType.getUpperBounds(); 54 55 if (lower.length > 0){ 56 for (int j = 0 ; j < lower.length; ++j){ 57 System.out.println(" lower[ " + j + " ] = " + lower[j].getTypeName()); 58 } 59 } 60 if (upper.length > 0){ 61 for (int k = 0 ; k < upper.length; ++k){ 62 System.out.println(" upper[ " + k + " ] = " + upper[k].getTypeName()); 63 } 64 } 65 } 66 } 67 }
第13行成员的类型是WildcardType,第14行成员的类型不是WildcardType,因为它没有通配符? .结果为 :
1 ------------------------------ 2 typeName = com.example.sjjg.utest.MockitoJava$UUU<java.lang.String, java.lang.Number> 3 actual[ 0 ] = java.lang.String 4 it is not WildcardType 5 actual[ 1 ] = java.lang.Number 6 it is not WildcardType 7 ------------------------------ 8 typeName = java.util.Map<? super java.lang.String, ? extends java.lang.Number> 9 actual[ 0 ] = ? super java.lang.String 10 lower[ 0 ] = java.lang.String 11 upper[ 0 ] = java.lang.Object 12 actual[ 1 ] = ? extends java.lang.Number 13 upper[ 0 ] = java.lang.Number