Type、TypeVariable、ParameterizedType、GenericArrayType、WildcardType、Class

1.官方文档      

Type https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/Type.html
GenericDeclaration https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/GenericDeclaration.html
TypeVariable https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/TypeVariable.html
ParameterizedType https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/ParameterizedType.html
GenericArrayType https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/GenericArrayType.html
WildcardType https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/WildcardType.html
Class https://docs.oracle.com/javase/8/docs/api/java/lang/Class.html

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

 

posted @ 2015-05-21 19:02  f9q  阅读(307)  评论(0编辑  收藏  举报