[TOC]
概述
Type是Java语言中所有类型的公共高级接口。
这个所有类型是从Java语言角度来说的,如上图可见(Class类也实现了该接口),Type体系包括了Class、参数化类型(ParameterizedType)、数组类型(GenericArrayType)、类型变量(TypeVariable)。
Type的使用
1.Class
type有一个实现类和4个实现接口,当需要描述的类型是:普通的类,自定义的类,也就是和 泛型无关的类 ,java可以直接将这个type类强转为Class。
2. TypeVariable
TypeVariable 是类型变量的常用超级接口。类型变量在反射方法首次需要时创建。指的是List
中的T,实际的Java类型是TypeVariableImpl。也可以对类型变量加上extend限定,这样会有类型变量对应的上限。
获取一个对象的泛型声明方式通常是通过class类,class类实现了GenericDecalaration接口,该接口只有一个方法,返回的是代表了泛型声明的泛型变量数组。
public interface GenericDeclaration extends AnnotatedElement {
public TypeVariable>[] getTypeParameters();
}
TypeVariable extends Class extends User>>[] typeVariables = user.getClass().getTypeParameters();
for (TypeVariable extends Class extends User>> typeVariable :typeVariables){
System.out.println(typeVariable.getName()); //输出T
Stream.of(typeVariable.getBounds()).forEach(System.out::println); //没有上限默认输出Object
System.out.println(typeVariable.getGenericDeclaration()); // 输出user,因为是在user类上声明的泛型
}
public interface TypeVariable extends Type, AnnotatedElement {
/**
*返回表示此类型变量上边界的Type对象数组
*/
Type[] getBounds();
/**
* Returns the {@code GenericDeclaration} object representing the
* generic declaration declared this type variable.
*
* @return the generic declaration declared for this type variable.
*
* @since 1.5
*/
D getGenericDeclaration();
/**
* Returns the name of this type variable, as it occurs in the source code.
*
* @return the name of this type variable, as it appears in the source code
*/
String getName();
}
3. ParameterizedType
表示一个参数化类型,也就是泛型,例如List
/**
* ParameterizedType represents a parameterized type such as
* Collection<String>.
*/
public interface ParameterizedType extends Type {
/**
* Returns an array of {@code Type} objects representing the actual type
* arguments to this type.
* 获取泛型中的实际类型
*/
Type[] getActualTypeArguments();
/**
* Returns the {@code Type} object representing the class or interface
* that declared this type.
*
* @return the {@code Type} object representing the class or interface
* that declared this type
* 获取声明泛型的类或者接口,也就是泛型中<>前面的那个值。
*/
Type getRawType();
/**
* Returns a {@code Type} object representing the type that this type
* is a member of. For example, if this type is {@code O.I},
* return a representation of {@code O}.
*
* If this type is a top-level type, {@code null} is returned.
*
* @return a {@code Type} object representing the type that
* this type is a member of. If this type is a top-level type,
* 获取泛型的拥有者
*/
Type getOwnerType();
}
通常,我们可以使用该接口来检验泛型是否被参数化。通过instance判断是已经参数化了之后,再通过getactualTypeArguments方法获取参数化类型。具体可参考下面的代码。
如何获取参数化类型
这里说的参数化类型指的就是泛型的实际形式,即将类型以参数的方式进行传递。这里需要注意的点是Java是共享泛型模式,子类的泛型标识在编译时就会被擦除,不会写入到实际子类型中,所以无法得到自身标识的类型参数。要想得到泛型信息,只能从上层类型中得到(可以是继承的父类或者实现的接口)。从下面的代码中也能看出,调用Son.getclass方法能够获得类型参数class.User,而调用Fathor的该方法时却会报错。从代码也能看出,我们得到的参数类型也不是通过构造方法传入的类型,而是从父类传递下来的参数类型。
public class Fathor {
public void getClazz(){
Type type = this.getClass().getGenericSuperclass();
System.out.println(type);
Type[] types = ((ParameterizedType)type).getActualTypeArguments();
Stream.of(types).forEach(System.out::println);
}
}
public class Son extends Fathor {
@Override
public void getClazz() {
Type type = this.getClass().getGenericSuperclass();
System.out.println(type);
if(type instanceof ParameterizedType) {
Type[] types = ((ParameterizedType)type).getActualTypeArguments();
Stream.of(types).forEach(System.out::println);
}
}
}
public static void main(String[] args) {
new Son().getClazz();
new Fathor().getClazz();
}
//输出
instance.Fathor
class instance.User
class java.lang.Object
Exception in thread "main" java.lang.ClassCastException: java.lang.Class cannot be cast to java.lang.reflect.ParameterizedType
at instance.Fathor.getClazz(Fathor.java:15)
at wytest.Test2.main(Test2.java:15)
4. GenericArrayType
泛型数组类型,例如List
public interface GenericArrayType extends Type {
//返回泛型数组中元素的Type类型,
Type getGenericComponentType();
}