深入解析Java中Type接口的来历与相关接口:从范型到反射的全面解析

原创专栏|石松

深入解析Java中Type接口的来历与相关接口:从范型到反射的全面解析

2015 年加入 Qunar 这个公司。目前在金融事业部工作,担任 JAVA 开发工程师一职。主要的工作是负责征信以及授信相关业务的开发。自身有着代码洁癖,一直致力于构建那种简单、易用并且高效的 SaaS 服务。

本文主要介绍在 java 中,Type 接口是从何而来的,并且还介绍了与之相关的几个接口。

通过这篇文章,我们能够了解到一些与范型相关的接口,并且对范型的分类有一定的认识。

可以了解到 Type 接口和 Class 类之间的关系,也可以了解到 Type 出现的原因。

反射相关接口

下面就把Type的来龙去脉彻底弄清楚。

Type

Type 是所有类型的父接口。它包含原始类型(对应 Class)、参数化类型(对应 ParameterizedType)、数组类型(对应 GenericArrayType)、类型变量(对应 TypeVariable)和基本(原生)类型(对应 Class)。子接口有 ParameterizedType、TypeVariable、GenericArrayType、WildcardType。实现类有 Class。

ParameterizedType

具体的范型类型, 如Map

有如下方法:

Type getRawType():此函数用于返回承载该泛型信息的对象。例如,像上面提到的那个 Map,它承载的泛型信息的对象就是 Map。

返回实际泛型类型列表。例如,上面那个 Map 的实际泛型列表中有两个元素,且这两个元素都是 String。

Type getOwnerType(),其作用是返回是谁的 member,这是两个较为常用的情况。

TypeVariable

类型变量,在编译时范型信息会被转换成一个特定的类型。而 TypeVariable 是用来反映在 JVM 编译该泛型之前的信息。

它的声明内容为:public interface TypeVariable ,并且该接口继承自 Type 。

它与 GenericDeclaration 存在一定联系,我对此的理解是:

它具有以下方法。

获取类型变量的上边界,若未明确声明上边界则默认为 Object。此方法的返回类型为 Type[]。

获取声明该类型变量实体的是 D 的 getGenericDeclaration()方法。

获取在源码中定义时的名字。获取其对应的名称。获取其原本的名字。获取在最初编写时的名字。获取在源头设定时的名字。获取在原始代码中定义的名字。获取在源码层面定义的名字。获取在源码里定义的名字。获取在源代码中规定的名字。获取在源代码里规定的名字。获取在源代码中设定的名字。获取在源代码中确定的名字。

注意:

GenericArrayType

范型数组,若其组成数组的元素中存在范型,那么就实现了该接口;其组成元素为 ParameterizedType 或 TypeVariable 类型,且它只有一个方法:

Type getGenericComponentType(),它的作用是返回数组的组成对象,也就是被 JVM 编译后实际的对象。

WildcardType

该接口所表示的是通配符泛型。例如? extends Number 以及? super Integer ,它具备以下这些方法:

获取范型变量的上界的类型为 Type[]。

获取范型变量的下界的类型为[]。

注意:

再写几个边界的例子:

它们最终统一成Type作为数组的元素类型。

Type及其子接口的来历

泛型出现之前的类型

在没有泛型的时候,仅存在原始类型。在这种情况下,所有的原始类型都是借助字节码文件类 Class 类来进行抽象的。Class 类的一个具体对象能够代表一个特定的原始类型。

泛型出现之后的类型

泛型出现之后,数据类型得到了扩充。从原本只有的原始类型,扩充到了参数化类型、类型变量类型、限定符类型以及泛型数组类型。

与泛型有关的类型不能和原始类型统一到Class的原因

原始类型和新产生的类型都需要统一为各自的字节码文件类型对象。然而,泛型并非最初 Java 所具备的成分。倘若真的将泛型加入进来,就会涉及到 JVM 指令集的修改,而这一修改是极为致命的。

Java采用泛型擦除机制来引入泛型,目的是使用泛型却不真正引入泛型。在 Java 中,泛型只是给编译器 javac 使用的,这样能确保数据的安全性,还能免去强制类型转换的麻烦。然而,一旦编译完成,所有与泛型有关的类型都会被全部擦除。

因此,参数化类型、类型变量类型、限定符类型以及泛型数组类型这些与泛型有关的类型,在编译后全部恢复为原始类型。在字节码文件中,它们都是泛型被擦除后的原始类型,不存在与自身类型对应的字节码文件。所以,和泛型相关的新扩充进来的类型无法被统一到 Class 类中。

Java新增了几种类型来通过反射操作那些不能被归一到 Class 类中的类型但又和原始类型齐名的类型,以迎合实际开发的需要,这些类型包括 ParameterizedType、TypeVariable、GenericArrayType、WildcardType。

为了使程序具有扩展性,最终引入了 Type 接口。这个 Type 接口成为了 Class、ParameterizedType、TypeVariable、GenericArrayType 和 WildcardType 这几种类型的总的父接口。通过这样的方式,能够使用 Type 类型的参数来接收上述五种类型的子类的实参,或者使返回值类型为 Type 类型的参数。统一了与泛型有关的类型和原始类型Class

从上面可以看出,Type 的出现只是起到了借助多态来实现程序扩展性提升的作用,不存在其他作用。所以在 Type 接口的源码里没有任何方法。

你可能想看:
« 上一篇
下一篇 »

相关推荐

java中什么是冒泡,冒泡算法

2026年09月06日

27阅读

java中冒号,java双冒号

2026年09月06日

26阅读

java中的->,java中的是什么意思

2026年09月06日

24阅读

java中的super用法,Java中super的说明

2026年09月06日

28阅读

java中反射的应用,java中反射的应用场景

2026年09月06日

25阅读

java中开关的定义,Java关键字有哪些

2026年09月06日

25阅读