Java反射之获取泛型类定义的具体类型

通过上一篇Java反射之表示所有类型的Type接口一文,我们知道 Type 接口及其五大组件是用来描述Java的各种类型,主要包括原始类型和泛型类型。很多时候,我们需要获取到泛型类上定义的具体类型,从而完成一些业务逻辑。比如,最常见的情景就是JSON的反序列化,需要将JSON字符串反序列化为泛型的具体类型,比如反序列化为 List<User>,这就要求每一个 List 中的元素都是 User 对象。那么,如何获取到泛型类上定义的具体类型呢?这就是本文要阐述的内容。 1. 通过Class能获取泛型类型吗? 在/2021/11/09/reflect-class.html中说过,Class 类上有一个 getTypeParameters() 方法用来获取类上的类型变量。通过它能不能获取到泛型类型呢?看下边的示例: class Parent<T> { (1) } 1 定义一个泛型类 这里定义一个泛型类,现在尝试通过它的实例对象来获取泛型类型,代码如下: public void printParent() { Parent<String> parent = new Parent<>(); (1) TypeVariable<? extends Class<? extends Parent>>[] parentTypeParameters = parent.getClass().getTypeParameters(); (2) System.out.println(Arrays.toString(parentTypeParameters)); } 1 创建 Parent 类的实例 2 获取类型变量 上边的示例并不能拿到实例上的 String 类型,而只能拿到 Parent 类上定义的泛型类型 T,因此,输出结果为: [T] 很显然,这个结果不是我们想要的,我们想要获取到 String 这个类。在 Java反射之创建泛型数组 一文中说过,泛型是编译期特性,在运行时泛型会被擦除。因此,我们想通过`Class` 在运行时用反射直接去获取泛型类型,看起来是不行的。 ...

2021-11-15 · 3 min · 495 words · Hank

Java反射之表示所有类型的Type接口

前边说过,JDK1.5推出了反射功能,并介绍了反射的类设计结构,其中提到了 Type 接口,它是JDK1.5新增的接口,表示Java中的所有类型。本文介绍这个接口及其五大组件。 Figure 1. Type及其组件 1. Type的五大组件概览 Type 接口表示Java中的类型,这些类型包括原始类型、参数化类型、数组类型、类型变量和基本类型,前边介绍的 Class 就是其组件之一。Type 及其组件用于通过反射来描述Java各种类型,比如描述泛型的定义,获取泛型参数个数、类型、泛型通配符的上下边界等等。一个典型的应用场景是获取真实的泛型类型,我们将在后续文章单独介绍。 Type 用其五大组件来描述上边提到这些类型,类图如下: Figure 2. Type类图 ParameterizedType: 表示参数化类型,即整个泛型的定义,如 List<String> 可以用 ParameterizedType 来描述; TypeVariable: 表示类型变量,即泛型申明中的具体类型,比如: List<E> 用参数化类型来描述,而其中的 E 就用 TypeVariable 来描述; WildcardType: 表示泛型通配符类型,即泛型申明中带 ? 通配符,比如:List<? extends Number> 中 ? extends Number 就用 WildcardType 来描述; GenericArrayType: 表示泛型数组,比如申明一个泛型数组的域 T[] array,它就用 GenericArrayType 来描述; Class: 表示运行时的类或接口,在前边Java反射的体系结构一文中已经介绍过了,不再赘述。 一句话总结,Type 的 Class 组件用来描述Java类或接口等原始类型和基本类型,其他几个组件描述泛型类型,包括泛型的变量、通配符以及泛型数组。 现在,来看看这几个组件的用法。 2. 参数化类型ParameterizedType 什么是参数化类型?其实就是指泛型,具体而言,JDK5推出泛型之后,原来的具体的类型可以申明为泛型,变得"可被参数化"了,比如:List 是一个具体类型,但是可以申明为 List<String>、List<Integer> ,就仿佛可以申明不同的参数,类似方法可以申明不同的参数一样(其实泛型是编译期特性,它两实际上是同一类型,都是 List,这在 Java反射之创建泛型数组 已经说过了)。 所以,ParameterizedType 用来描述泛型类型,比如:List<T>、List<String>、User<T extends Number>、List<? super User> 都可以用它来描述。ParameterizedType 的定义如下: ...

2021-11-14 · 4 min · 804 words · Hank