1、Type 接口简介
Type 是 Java 语言中所有类型的公共父接口,其从 JDK5 开始引入,引入的目的主要是为了支持泛型。
Type 和 泛型、反射 息息相关,建议先了解这两个概念再了解 Type,不然下面的内容肯定看不明白。
没有泛型的之前,Java 只有所谓的原始类型(raw types)。此时,所有的原始类型都通过字节码类 Class 进行抽象。Class 类的一个具体对象(例如 String.class)就代表一个指定的原始类型。
泛型的出现扩充了数据类型的概念,从只有原始类型(raw types)扩充了参数化类型、类型变量类型、泛型数组类型和通配符类型。他们都是 Type 的子接口。
为什么他们没有统一到 Class 下,而是增加一个 Type 呢?个人认为,主要是因为这几个新增的类型和之前的 Class 有比较大的区别,Class 源码有近四千行,对外提供的方法有一百多个,而新增的这几个类型接口中声明的方法都不超过 5 个。
// Type is the common superinterface 公共父接口 for all types in the Java programming language.
// These include raw types, parameterized types, array types, type variables and primitive types.
// @since 1.5
public interface Type {
// Returns a string describing this type, including information about any type parameters.
default String getTypeName() {
return toString();
}
}
// Class 也是 Type 的一个实现类
class Class<T> implements Serializable, GenericDeclaration, Type, AnnotatedElement
- 所有已知子接口:
GenericArrayType,ParameterizedType,TypeVariable<D>,WildcardType - 所有已知实现类:
Class
2、Java 中的所有类型
-
raw type:原始类型,对应
Class- 即我们通常说的引用类型,包括普通的类,例如
String.class、List.class - 也包括数组(
Array.class)、接口(Cloneable.class)、注解(Annotation.class)、枚举(Enum.class)等
- 即我们通常说的引用类型,包括普通的类,例如
-
primitive types:基本类型,对应
Class- 包括
Built-in内置类型,例如int.class、char.class、void.class - 也包括
Wrappers内置类型包装类型,例如Integer.class、Boolean.class、Void.class
- 包括
-
parameterized types:参数化类型,对应
ParameterizedType- 带有类型参数的类型,即常说的泛型,例如
List<T>、Map<Integer, String>、List<? extends Number> - 实现类
sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
- 带有类型参数的类型,即常说的泛型,例如
-
type variables:类型变量类型,对应
TypeVariable<D>- 即参数化类型 ParameterizedType 中的 E、K 等类型变量,表示泛指任何类
- 实现类
sun.reflect.generics.reflectiveObjects.TypeVariableImpl
-
array types:泛型数组类型,对应
GenericArrayType- 元素类型是参数化类型或者类型变量的泛型数组类型,例如
T[] - 实现类
sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl
- 元素类型是参数化类型或者类型变量的泛型数组类型,例如
Type 接口的另一个子接口
WildcardType代表通配符表达式类型,或泛型表达式类型,比如?、? super T、? extends T,他并不是 Java 类型中的一种。
2.1、 ParameterizedType
ParameterizedType是Type的子接口,表示一个有参数的类型,例如Collection,Map<K,V>等。但实现上 ParameterizedType并不直接表示Collection和Map<K,V>等,而是表示 Collection和Map<String,String>等这种具体的类型。是不是看着眼熟,其实这就是我们常说的泛型。而ParameterizedType代表的是一个泛型的实例,我们就称ParameterizedType为“泛型实例”吧。
当创建泛型P(如:Collection)时,将解析P实例化的泛型类型声明(如:Collection),并且递归地创建P的所有泛型参数(如:String)。
实现这个接口的“类”必须实现一个equals()方法,该方法将任何“泛型类型”(如:Collection)声明相同且“类型参数”(如:String)也相同的两个“类”等同起来。
2.1.1、Type[] getActualTypeArguments()
获取“泛型实例”中<>里面的“泛型变量”(也叫类型参数)的值,这个值是一个类型。因为可能有多个“泛型变量”(如:Map<K,V>),所以返回的是一个Type[]。
注意:无论<>中有几层<>嵌套,这个方法仅仅脱去最外层的<>,之后剩下的内容就作为这个方法的返回值,所以其返回值类型是不确定的。
煮个栗子:
- List a1;//返回ArrayList,Class类型
- List<ArrayList> a2;//返回ArrayList,ParameterizedType类型
- List a3;//返回T,TypeVariable类型
- List<? extends Number> a4; //返回
? extends Number,WildcardType类型 - List<ArrayList[]> a5;//返回ArrayList[],GenericArrayType 类型
2.1.2、Type getRawType()
声明泛型的类或者接口,也就是泛型中<>前面的那个值,即Map<K ,V>的Map。
2.1.3、Type getOwnerType()
获得这个类型的所有者的类型。这主要是对嵌套定义的内部类而言的,例如于对java.util.Map.Entry<K,V>来说,调用getOwnerType方法返回的就是interface java.util.Map。
如果当前类不是内部类,而是一个顶层类,那么getOwnerType方法将返回null。
3、variables 类型变量
类上获取类型变量
if(actualType instanceof Class){
typeParameters = ((Class) actualType).getTypeParameters();
}
参考:www.cnblogs.com/baiqiantao/… 参考:blog.csdn.net/liyantianmi…