理解Type类型

整理自:https://blog.csdn.net/qq_30770095/article/details/79016257

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

Type的来历

  我们知道,Type是JDK5开始引入的,其引入主要是为了泛型,没有泛型的之前,只有所谓的原始类型。此时,所有的原始类型都通过字节码文件类Class类进行抽象。Class类的一个具体对象就代表一个指定的原始类型。

  泛型出现之后,也就扩充了数据类型。从只有原始类型扩充了参数化类型、类型变量类型、泛型数组类型,也就是Type的子接口。

  那为什么没有统一到Class下,而是增加一个Type呢?(Class也是种类的意思,Type是类型的意思)

  是为了程序的扩展性,最终引入了Type接口作为Class,ParameterizedType,GenericArrayType,TypeVariable和WildcardType这几种类型的总的父接口。这样实现了Type类型参数接受以上五种子类的实参或者返回值类型就是Type类型的参数。

 

1.原始类型

Class表示的是原始类型。Class类的对象表示JVM中的一个类或者接口,每个java类在JVM都表现为一个Class对象。可以通过“类名.Class”、“对象.getClass()”或者Class.forName("类名")等方法获取到Class对象。数组也被映射为Class对象,所有元素类型相同且维度相同的数组都共享同一个Class对象。

2.参数化类型

ParameterizedType表示的是参数化类型,例如List<String>、Map<Integer,String>、Service<User>这种带有泛型的类型。

3.类型变量

TypeVariable表示的是类型变量。例如List<T>中的T就是类型变量

4.范型数组

GenericArrayType表示的是数组类型且组成元素是ParameterizedType或者是TypeVariable,例如List<String>[] 或 T[]。

5.通配符类型

WildcardType表示的是通配符泛型,例如<? extends Number>

 

ParmeterizedType(参数化类型)

即为参数化类型,就是将类型进行参数化,把类型当做参数传入

参数化类型一般用来表示如List<T>,注意应该当成一个整体来进行看待

parameterizedType表示的类型非常的简单,只要带着泛型,除了不可以是数组和本类上定义的泛型以外,其他都被列入ParameterizedType的范围。

具体的方法可以自行查询API,这里不进行介绍,只是帮助理解。

public class Type{
    public List<String> list;
    private  List<String>[] list1;
    private  List list2;
    Map.Entry<String,Integer> entry;
    String str = new String();
    T t;
}
    public static void main(String[] args) throws ClassNotFoundException {
        Class<Type> type = (Class<Type>) Class.forName("test.Type");
        Field[] fields = type.getDeclaredFields();
        for (Field field : fields) {
            System.out.println("field name is :" + field.getName());
            System.out.print("instanceof ParameterizedType");
            System.out.println("            " + (field.getGenericType() instanceof ParameterizedType));
            System.out.println("type       "+field.getGenericType().getClass());
            if ("entry".equals(field.getName())) {
                ParameterizedType t = (ParameterizedType) field.getGenericType();
                System.out.println("ownerType   "+t.getOwnerType());
                System.out.println("rawType     "+t.getRawType());
                Type[] actualTypeArguments = t.getActualTypeArguments();
                for (Type type2 : actualTypeArguments) {
                    System.out.println("actualTypeArguments   :" + type2.getTypeName());
                }
            }
            System.out.println();
        }
    }

运行结果

field name is :list
instanceof ParameterizedType            true
type       class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl

field name is :list1
instanceof ParameterizedType            false
type       class sun.reflect.generics.reflectiveObjects.GenericArrayTypeImpl

field name is :list2
instanceof ParameterizedType            false
type       class java.lang.Class

field name is :entry
instanceof ParameterizedType            true
type       class sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl
ownerType   interface java.util.Map
rawType     interface java.util.Map$Entry
actualTypeArguments   :java.lang.String
actualTypeArguments   :java.lang.Integer

field name is :str
instanceof ParameterizedType            false
type       class java.lang.Class

field name is :t
instanceof ParameterizedType            false
type       class sun.reflect.generics.reflectiveObjects.TypeVariableImpl

解释

  1. List<String> list 是ParameterizedType。
  2. List<String>[] list1由于是数组,所以不是ParameterizedType,应该是GenericArrayType。
  3. List list2由于没有带泛型,所以也不是ParameterizedType,应该是Class,也就是原始类型。
  4. Map.Entry<String,Integer> entry 是parameterizedType,我们进一步使用了ParameterizedType的3个方法演示给大家看。我们可以看到ownerType是Entry的外部类Map。这也印证了获取到的类型Map为原类型,Map.Entry是其成员之一,而rawType则是其自身类型。getActualTypeArguments()获取到的Type数组则是泛型中的所有类型。(例如Map<k,v>则获取到的数组中包含k,v这两个类型。并且k在前,v在后。)
  5. String str = new String();由于没有带泛型所有不是parameterizedType,应该是Class。
  6. T t 由于是本类上定义的泛型,所以也不行,应该是类型变量。

TypeVariable(类型变量)

public class Type<T extends Integer> {
    T t;
}
public static void main(String[] args) throws ClassNotFoundException {
    Class<Type> type = (Class<Type>) Class.forName("test.Type");
    Field[] fields = type.getDeclaredFields();
    for (Field field : fields) {
        System.out.println("field name is :" + field.getName());
        System.out.println("type       " + field.getGenericType().getClass());
        TypeVariable t = (TypeVariable) field.getGenericType();
        System.out.println("declaration   " + t.getGenericDeclaration());
        System.out.println("up bound     " + t.getBounds()[0]);
    }
}
field name is :t
type       class sun.reflect.generics.reflectiveObjects.TypeVariableImpl
declaration   class test.Type
up bound     class java.lang.Integer

解释

declaration:声明该类型遍历的类,上边界Integer,如果没有声明上边界,则默认为Object。

GenericArrayType(泛型数组类型)

顾名思义,只要是带泛型的,并且是数组的那就属于GenericArrayType的范畴。

WildcardType(通配符类型)

表示通配符类型参数。

WildcardType是依托于ParameterizedType和GenericArrayType

例如:

Class<?>
List<? extends Number>
Set<? super T>

 

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值