谈谈Java中的Class和Type

166 阅读2分钟

Class

java中所有的类都可以使用Class来表示,Class中存储了java对象的所有信息。在特殊场景也可以通过反射通过Class做更多的事。在java中万事万物皆对象的概念下,Class可以说包含了所有。但是到了jdk1.5后,引入了范型的特性。Class面对范型就显得束手无策了,这个时候Type登场了。在Class中有两个很相近的方法

//获取父类类型,不带范型参数。比如:Base
public native Class<? super T> getSuperclass();

//获取父类类型,带范型参数。比如:Base<T>
public Type getGenericSuperclass();

在上面的代码中可以看到,如果不带范型参数可以直接返回Class。如果带了范型参数返回的是Type对象。那么Type到底是什么呢?

Type

image.png java中的Type是在jdk1.5增加范型特性的时候一起新增的,可以说Type就是跟范型绑定在一起的。在设计上,Class用来处理原始类型;其他类型的Type用来处理范型。 又因为java范型会被擦除(java中的范型是伪范型,表面范型,实质不是范型。原因在于加入范型会对jvm指令集进行修改,代价过大),所以Class也是Type的子类。Type的出现弥补了Class对范型的缺点。

Type详解

ParameterizedType 参数化类型

带有泛型的类型,也就是带有参数化类或者接口对应的类型,例如 List<String> listMap<String,Integer> map 等对应的类型均是ParameterizedType类型

public interface ParameterizedType extends Type {
    // 获取类型内部的参数化类型,比如Map<K,V>里面的K,V类型; 
    // 注意该方法只返回最外层的<>中的类型,无论该<>内有多少个<>。 
    Type[] getActualTypeArguments(); 
    // 类的原始类型,一般都是Class 
    Type getRawType(); 
    // 获取所有者类型(只有内部类才有所有者,比如Map.Entry的所有者就是Map),如果不是内部类,返回null。 
    Type getOwnerType(); 
}

TypeVariable 类型变量

泛型本身的类型,例如 HashMap<K,V>中的 K,V

public interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement { 
    // 类型变量对应的上边界,如果没有指定上限,返回Object 可以有多个 
    Type[] getBounds(); 
    // 获取类型变量所在类的Type,比如TypeVariableTest<T>类,getGenericDeclaration()得到的就是TypeVariableTest。 
    D getGenericDeclaration(); 
    // 获取类型变量在源码中定义的名称 
    String getName(); 
    //获取注解类型的上限数组 
    AnnotatedType[] getAnnotatedBounds(); 
}

GenericArrayType 数组类型

带有泛型的数组类型,也就是带有参数化类或者接口所表示的数组对应的类型,例如 List<String>[] listMap<String,Integer> map[]等对应的类型均是GenericArrayType类型,而List[] listMap[] map是Class类型

public interface GenericArrayType extends Type { 
    // 返回泛型数组中成员类型,即List<String>[]中的List<String> 
    Type getGenericComponentType(); 
}

WildCardType 通配符类型

通配符对应的类型,例如 List<? extends Object> ?对应的类型

public interface WildcardType extends Type { 
    // 获得泛型表达式上边界,表达式中使用extends 
    Type[] getUpperBounds(); 
    // 或者泛型表达式的下边界,表达式中使用super 
    Type[] getLowerBounds(); 
}