Type 只在反射 中才有真正的意义,表示 Java 中所有类型的公共父接口。它包含:原始类型、参数化类型、数组类型、类型变量和基础数据类型。  
 
Java 语言规范中指出变量只有下面三种类型 JLS :  
基本类型 primitive types:boolean, byte, short, int, long, char, float, double   
引用类型 reference types:class, interface, array, type variables   
空类型 null type   
 
关于泛型和语言规范中三种类型的关系如下:  
如果类或接口声明了类型变量,那么它就是泛型   
类和接口如果是泛型,那么它就定义了一个参数化类型,简单理解为泛型就是参数化类型。但是参数化类型是属于类类型或者接口类型的   
参数化类型的参数 Type Arguments of Parameterized Types:可以是引用类型和通配符   
 
在学习 Type 及子接口或实现类时,很容易将它们和语言规范中的类型混淆。语言规范简单来讲类型分为:基本数据类型,类类型(包含接口),数组(另外算上一个类型变量)。总是在想:为什么会多出 Type 这几种类型?它们和基本语言规范中类型的区别是什么呢?实际上从语言规范中的类型来讲,它们是标准的类类型(包含接口),只有在反射解析变量时,它们才有实际的意义,用来区分泛型的几种情景。  
 
类图结构 
Type 基本概念Type 的引入主要是为了反射和泛型服务的,它能代表一切类型。在编码使用中(抛开反射概念),这几种类型是标准的类类型和接口类型;它们只能在反射 中才能体现真正的意义,能代表泛型的几种细分场景:  
Type 表示 Java 中所有类型的公共接口。也就是反射 中 Type 代表 Java 语言规范中的所有类型。   
TypeVariable 表示类型变量,即泛型中的 T, K, V 等等。   
ParameterizedType 表示参数化类型,即泛型,如:Collection<String> 。   
GenericArrayType 表示数组中的:参数化类型数组,类型变量数组,如:Collection<String>[], T[] 。并不包含基本类型和类类型数组。   
WildcardType 表示通配符类型表达式,如 ?,? extends Number,? super Integer 。它只是参数化类型中参数的一种类型,无法直接修饰变量。   
Class 它是 Type 的实现类,表示除了上面泛型中的几个特定类型之外的所有类型 ,包含基本数据类型,引用类型等。每个类在加载后都会对应一个 Class 类对象,它包含了 .class 文件转换为内存运行时数据结构,也就是包含类中的一切信息。参考:类加载机制    
 
Class 对象是否反射的基石 ,在 Java 中使用 类名.clas 表示类对象。如:String.class, Object.class 等等。  
源码分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 public  interface  Type   {         default  String getTypeName ()   {         return  toString();     } } public  interface  ParameterizedType  extends  Type   {         Type[] getActualTypeArguments();          Type getRawType ()  ;          Type getOwnerType ()  ; } public  interface  TypeVariable <D  extends  GenericDeclaration >     extends  Type , AnnotatedElement   {         Type[] getBounds();          D getGenericDeclaration ()  ;          String getName ()  ;           AnnotatedType[] getAnnotatedBounds(); } public  interface  GenericArrayType  extends  Type   {         Type getGenericComponentType ()  ; } public  interface  WildcardType  extends  Type   {         Type[] getUpperBounds();          Type[] getLowerBounds(); } public  final  class  Class <T > implements  Serializable ,     GenericDeclaration , Type , AnnotatedElement   {...}
 
示例 源码 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 public  class  TestType   {    private  void  testParameterizedType ()  {         class  ParameterizedTypeTestClass  {             List<String> list;             Map.Entry<Integer, String> entry;             Class<?> clazz;         }         showTypeDetails(ParameterizedTypeTestClass.class);     }     private  void  testTypeVariable ()  {         class  TypeVariableTestClass <K  extends  Runnable , V >  {             K k;             V v;             List<K> list;         }         showTypeDetails(TypeVariableTestClass.class);     }     private  void  testGenericArrayType ()  {         class  GenericArrayTypeTestClass <T > {             List<String>[] lists;             T[] ts;         }         showTypeDetails(GenericArrayTypeTestClass.class);     }     private  void  testWildcardType ()  {         class  WildcardTypeTestClass  {             List<? extends Number> numbers;             List<? super  Integer> list;         }         showTypeDetails(WildcardTypeTestClass.class);     }          private  void  testAllTypes ()  {         class  AllTypes  {             int  i;             boolean  b;             float  f;             byte [] bytes;             String s;             Object o;             Runnable runnable;             Object[] os;         }         showTypeDetails(AllTypes.class);     }     private  void  showTypeDetails (Class<?> clazz)  {         Field[] fields = clazz.getDeclaredFields();         for  (Field field : fields){             System.out.println("*************************" );             System.out.println("showTypeDetails: "  + clazz);             System.out.println("Field: "  + field);             Type type = field.getGenericType();             System.out.println("TypeName: "  + type.getTypeName());             if  (type instanceof  ParameterizedType) {                 ParameterizedType parameterizedType =(ParameterizedType)type;                 System.out.println("ParameterizedType--RawType: "                       + parameterizedType.getRawType());                 System.out.println("ParameterizedType--OwnerType: "                       + parameterizedType.getOwnerType());                 Type[] types = parameterizedType.getActualTypeArguments();                 System.out.println("ParameterizedType--Args.length = "                       + types.length);                 for  (Type t : types){                 System.out.println("ParameterizedType--ActualTypeArguments: "                      + t);                     if  (t instanceof  WildcardType){                         WildcardType wildcardType = (WildcardType) t;                         Type[] uppers = wildcardType.getUpperBounds();                         System.out.println("WildcardType--uppers.length = "                              + uppers.length);                         for  (Type t1 : uppers) {                             System.out.println("WildcardType--uppers, type ="                                  + t1);                         }                         Type[] lowers = wildcardType.getLowerBounds();                         System.out.println("WildcardType--lowers.length = "                              + lowers.length);                         for  (Type t2 : lowers){                             System.out.println("WildcardType--lowers. type ="                                  + t2);                         }                     }                 }             } else  if  (type instanceof  TypeVariable) {                 TypeVariable typeVariable = (TypeVariable) type;                 Type[] types = typeVariable.getBounds();                 System.out.println("TypeVariable--Bounds.length = "                      + types.length);                 for  (Type t : types){                     System.out.println("TypeVariable--Bounds = "  + t);                 }                 System.out.println("TypeVariable--GenericDeclaration = "                      + typeVariable.getGenericDeclaration());                 System.out.println("TypeVariable--Name = "                      + typeVariable.getName());             } else  if  (type instanceof  GenericArrayType) {                 GenericArrayType genericArrayType = (GenericArrayType) type;                 System.out.println("GenericArrayType--ComponentType: "                      + genericArrayType.getGenericComponentType());             } else  if  (type instanceof  Class) {                 System.out.println("Class--SimpleName = "                       + ((Class) type).getSimpleName());             }         }     }          public  static  void  main (String[] args)   {         TestType testType = new  TestType();         testType.testParameterizedType();         testType.testTypeVariable();         testType.testGenericArrayType();         testType.testWildcardType();     } } 
 
源码解析:  
反射后的字段类型 只有四种:ParameterizedType, TypeVariable, GenericArrayType, Class,它们的公共父接口为 Type 。   
反射后参数化类型的参数 类型为:通配符 WildcardType 和上面四种类型。  1 2 3 4 5 6 Class<?> clazz;                      List<? extends Number> numbers;      List<List<String>> listList;         List<K> listK;                       List<V[]> listVArray;                List<String> list;                   
 
 
 
结果分析 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 ************************* // 传入的类名为 TestType 的内部类 1ParameterizedTypeTestClass showTypeDetails: class com.***.TestType$1ParameterizedTypeTestClass // 获取的字段为 list,类型为:参数化类型 List<String>, // 其原始类型为 List,参数为 String Field: java.util.List com.***.TestType$1ParameterizedTypeTestClass.list TypeName: java.util.List<java.lang.String> ParameterizedType--RawType = interface java.util.List ParameterizedType--OwnerType = null ParameterizedType--Args.length = 1 ParameterizedType--ActualTypeArguments = class java.lang.String ************************* showTypeDetails: class com.***.TestType$1ParameterizedTypeTestClass Field: java.util.Map$Entry com.***.TestType$1ParameterizedTypeTestClass.entry TypeName: java.util.Map.java.util.Map$Entry<java.lang.Integer, java.lang.String> ParameterizedType--RawType = interface java.util.Map$Entry ParameterizedType--OwnerType = interface java.util.Map ParameterizedType--Args.length = 2 ParameterizedType--ActualTypeArguments = class java.lang.Integer ParameterizedType--ActualTypeArguments = class java.lang.String ************************* showTypeDetails: class com.***.TestType$1ParameterizedTypeTestClass // 获取的字段为 clazz,类型为:参数化类型 Class<?> Field: java.lang.Class com.***.TestType$1ParameterizedTypeTestClass.clazz TypeName: java.lang.Class<?> ParameterizedType--RawType = class java.lang.Class ParameterizedType--OwnerType = null ParameterizedType--Args.length = 1 ParameterizedType--ActualTypeArguments = ? // 其参数为通配符类型 WildcardType--uppers.length = 1 WildcardType--uppers, type = class java.lang.Object WildcardType--lowers.length = 0 ************************* // 内部类持有外部类的引用   showTypeDetails: class com.***.TestType$1ParameterizedTypeTestClass Field: final com.***.TestType com.***.TestType$1ParameterizedTypeTestClass.this$0 TypeName: com.***.TestType Class--SimpleName = TestType ************************* showTypeDetails: class com.***.TestType$1TypeVariableTestClass // 获取的字段为 k,类型为:类型变量 K Field: java.lang.Runnable com.***.TestType$1TypeVariableTestClass.k TypeName: K TypeVariable--Bounds.length = 1 TypeVariable--Bounds = interface java.lang.Runnable TypeVariable--GenericDeclaration = class com.***.TestType$1TypeVariableTestClass TypeVariable--Name = K ************************* showTypeDetails: class com.***.TestType$1TypeVariableTestClass Field: java.lang.Object com.***.TestType$1TypeVariableTestClass.v TypeName: V TypeVariable--Bounds.length = 1 TypeVariable--Bounds = class java.lang.Object TypeVariable--GenericDeclaration = class com.***.TestType$1TypeVariableTestClass TypeVariable--Name = V ************************* showTypeDetails: class com.***.TestType$1TypeVariableTestClass Field: java.util.List com.***.TestType$1TypeVariableTestClass.list TypeName: java.util.List<K> ParameterizedType--RawType = interface java.util.List ParameterizedType--OwnerType = null ParameterizedType--Args.length = 1 ParameterizedType--ActualTypeArguments = K ************************* showTypeDetails: class com.***. TestType$ 1TypeVariableTestClass Field: final com.***.TestType com.***.TestType$1TypeVariableTestClass.this$0 TypeName: com.***.TestType Class--SimpleName = TestType ************************* showTypeDetails: class com.***.TestType$1GenericArrayTypeTestClass // 获取字段为 lists,类型为:泛型数组 List<String>[] Field: java.util.List[] com.***.TestType$1GenericArrayTypeTestClass.lists TypeName: java.util.List<java.lang.String>[] GenericArrayType--ComponentType = java.util.List<java.lang.String> ************************* showTypeDetails: class com.***.TestType$1GenericArrayTypeTestClass Field: java.lang.Object[] com.***.TestType$1GenericArrayTypeTestClass.ts TypeName: T[] GenericArrayType--ComponentType = T ************************* showTypeDetails: class com.***.TestType$1GenericArrayTypeTestClass Field: final com.***.TestType com.***.TestType$1GenericArrayTypeTestClass.this$0 TypeName: com.***.TestType Class--SimpleName = TestType ************************* showTypeDetails: class com.***.TestType$1WildcardTypeTestClass // 获取字段为 numbers,类型为:参数化类型 // 参数化类型的参数为:通配符 Field: java.util.List com.***.TestType$1WildcardTypeTestClass.numbers TypeName: java.util.List<? extends java.lang.Number> ParameterizedType--RawType = interface java.util.List ParameterizedType--OwnerType = null ParameterizedType--Args.length = 1 ParameterizedType--ActualTypeArguments = ? extends java.lang.Number WildcardType--uppers.length = 1 WildcardType--uppers, type = class java.lang.Number WildcardType--lowers.length = 0 ************************* showTypeDetails: class com.***.TestType$1WildcardTypeTestClass Field: java.util.List com.***.TestType$1WildcardTypeTestClass.list TypeName: java.util.List<? super java.lang.Integer> ParameterizedType--RawType = interface java.util.List ParameterizedType--OwnerType = null ParameterizedType--Args.length = 1 ParameterizedType--ActualTypeArguments = ? super java.lang.Integer WildcardType--uppers.length = 1 WildcardType--uppers, type = class java.lang.Object WildcardType--lowers.length = 1 WildcardType--lowers. type = class java.lang.Integer ************************* showTypeDetails: class com.***.TestType$1WildcardTypeTestClass Field: final com.***.TestType com.***.TestType$1WildcardTypeTestClass.this$0 TypeName: com.***.TestType Class--SimpleName = TestType ************************* // 获取基本数据类型、非泛型数组字段 showTypeDetails: class com.***.TestType$1AllTypes Field: int com.***.TestType$1AllTypes.i TypeName: int Class--SimpleName = int ************************* showTypeDetails: class com.***.TestType$1AllTypes Field: boolean com.***.TestType$1AllTypes.b TypeName: boolean Class--SimpleName = boolean ************************* showTypeDetails: class com.***.TestType$1AllTypes Field: float com.***.TestType$1AllTypes.f TypeName: float Class--SimpleName = float ************************* showTypeDetails: class com.***.TestType$1AllTypes Field: byte[] com.***.TestType$1AllTypes.bytes TypeName: byte[] Class--SimpleName = byte[] ************************* showTypeDetails: class com.***.TestType$1AllTypes Field: java.lang.String com.***.TestType$1AllTypes.s TypeName: java.lang.String Class--SimpleName = String ************************* showTypeDetails: class com.***.TestType$1AllTypes Field: java.lang.Object com.***.TestType$1AllTypes.o TypeName: java.lang.Object Class--SimpleName = Object ************************* showTypeDetails: class com.***.TestType$1AllTypes Field: java.lang.Runnable com.***.TestType$1AllTypes.runnable TypeName: java.lang.Runnable Class--SimpleName = Runnable ************************* showTypeDetails: class com.***.TestType$1AllTypes Field: final com.***.TestType com.***.TestType$1AllTypes.this$0 TypeName: com.***.TestType Class--SimpleName = TestType 
 
参考文档