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 | /** |
示例
源码
1 | public class TestType { |
源码解析:
- 反射后的字段类型
只有四种:ParameterizedType, TypeVariable, GenericArrayType, Class
,它们的公共父接口为Type
。 - 反射后参数化类型的参数
类型为:通配符WildcardType
和上面四种类型。1
2
3
4
5
6Class<?> clazz; // WildcardType
List<? extends Number> numbers; // WildcardType
List<List<String>> listList; // ParameterizedType
List<K> listK; // TypeVariable
List<V[]> listVArray; // GenericArrayType
List<String> list; // Class
结果分析
1 | ************************* |