java中的Type

前言

Java 编程语言从Java 5以后就引入Type体系,大大方便了我们代码的编写和优化,但是当泛型擦除时,擦除类型变量,并替换为限定类型,此时我们在运行时期便无法获取泛型类原本所带的泛型。所以java引入了Type这一概念。Type也主要是为在运行时期获取泛型而服务。


一、Type是什么?

Type是一个空接口,所有类型的公共接口,其意义表示Java所有类型,这里的类型是从Java整个语言角度来看的,比如原始类型、参数化类型(泛型)、类型变量及其泛型数组等,可以理解为,Class是Java对现实对象的抽象,而Type是对Java语言对象的抽象。

二、Type接口

public interface Type {
    /**
     * Returns a string describing this type, including information
     * about any type parameters.
     *
     * @implSpec The default implementation calls {@code toString}.
     *
     * @return a string describing this type
     * @since 1.8
     */
    default String getTypeName() {
        return toString();
    }
}

实现了Type接口的子接口为GenericArrayType(泛型数组类型),ParmeterizedType(参数化类型),TypeVariable(类型变量),WildcardType(通配符类型)。实现了Type接口的子类有Class(类)。所以Type一共可以表示这5类数据。主要介绍的就是四个子接口。
在这里插入图片描述

二、ParameterizedType(参数化类型)

parameterizedType主要是用来表示带参数的类型,如 Collection、HashMap<String,Integer>等。parameterizedType表示的类型非常的简单,只要带着泛型,除了不可以是数组和本类上定义的泛型以外,其他都被列入ParameterizedType的范围。


package java.lang.reflect;

public interface ParameterizedType extends Type {
    //获取参数类型<>里面的泛型,例如Map<K,V> 那么就得到 [K,V]的一个数组
    Type[] getActualTypeArguments();
    //获取原始类型,例如例如Map<K,V> 那么就得到 Map
    Type getRawType();
    //获取其父类的类型,例如Map有一个内部类Entry, 那么在Map.Entry<K,V> 上调用这个方法就可以获得Map
    Type getOwnerType();
}

三、TypeVariable

类型变量,例如List中的T, Map<K,V>中的K和V

interface TypeVariable<D extends GenericDeclaration> extends Type, AnnotatedElement {
    //返回此类型参数的上界列表,如果没有上界则放回Object. 例如  V extends Person 这个类型参数,有1个上界Person
    Type[] getBounds();
    //类型参数声明时的载体,例如 `class HashMap<K, V >` ,那么V 的载体就是HashMap
    D getGenericDeclaration();
    String getName();
    //返回一个AnnotatedType对象的数组,表示使用类型来表示此TypeVariable表示的类型参数的上限。
    //即如果这个这个泛型参数类型的上界用注解标记了,我们可以通过它拿到相应的注解。
    AnnotatedType[] getAnnotatedBounds();
}

从typeVariable的定义看到它也有一个泛型参数,要求需要是GenericDeclaration 的子类。interface TypeVariable < D extends GenericDeclaration >.

//所有可以申明泛型参数的entities都必须实现这个接口
 public interface GenericDeclaration extends AnnotatedElement {     
    public TypeVariable<?>[] getTypeParameters();
}

而三个类实现了这个接口,分别是:

java.lang.reflect.Method,
java.lang.reflect.Constructor,
java.lang.Class

所以我们只能在类型(Class,Interface)、方法和构造函数这三个地方声明泛型参数,其他地方不能使用。

四、GenericArrayType

泛型数组类型,用来作为数组的泛型声明类型。例如List[] ltArray, T[] tArray两个数组,其中List[], 和T[]就是GenericArrayType`类型。

public interface GenericArrayType extends Type {
    //获取泛型类型数组的声明类型,即获取数组方括号 [] 前面的部分
    Type getGenericComponentType();
}

GenericArrayType 接口只有一个方法 getGenericComponentType(),其可以用来获取数组方括号 [] 前面的部分,例如T[],在其上调用getGenericComponentType 就可以获得T. 值得注意的是多维数组得到的是最后一个[] 前面的部分,例如T[][], 得到的是T[].

五、WildcardType

通配符类型,即带有?的泛型参数, 例如 List<?>中的?,List<? extends Number>里的? extends Number 和List<? super Integer>的? super Integer 。

public interface WildcardType extends Type {
   // 获取上界
    Type[] getUpperBounds();
    //获取下界
    Type[] getLowerBounds();
}

总结

Type类型平时很少遇到,但是翻阅JDK的源码时,有时候就会遇到,对于Type类型有所了解,能够加快我们对于代码的理解。亦如在JDK8之HashMap的comparableClassFor方法

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值