在反射中,我们经常遇到这样代码:ParameterizedType、getGenericSuperclass、getActualTypeArguments,今天就让我们来了解一下。
先来看一段代码:
这段代码啥意思?引用一段测试代码:
public class Person<T> {
}
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
public class Student extends Person<Student> {
public static void main(String[] args) {
Student st = new Student();
Class clazz = st.getClass();
// getSuperclass()获得该类的父类
System.out.println(clazz.getSuperclass()); // 输出:class com.test.Person
// getGenericSuperclass()获得带有泛型的父类
// Type是 Java 编程语言中所有类型的公共高级接口。它们包括原始类型、参数化类型、数组类型、类型变量和基本类型。
Type type = clazz.getGenericSuperclass();
System.out.println(type); // 输出:com.test.Person<com.test.Student>
// ParameterizedType参数化类型,即泛型
ParameterizedType p = (ParameterizedType)type;
// 获得父类的泛型参数的实际类型
// getActualTypeArguments返回的是一个数组,泛型参数的实际类型可能有多个
Class c = (Class) p.getActualTypeArguments()[0]; // 取数组第1个
System.out.println(c); // 输出:class com.test.Student
}
}
Type是什么?
Type是Java 编程语言中所有类型的公共高级接口(官方解释),也就是Java中所有类型的“爹”;其中,“所有类型”的描述尤为值得关注。它并不是我们平常工作中经常使用的 int、String、List、Map等数据类型,而是从Java语言角度来说,对基本类型、引用类型向上的抽象;
Type体系中类型的包括:原始类型(Class)、参数化类型(ParameterizedType)、数组类型(GenericArrayType)、类型变量(TypeVariable)、基本类型(Class);
原始类型,不仅仅包含我们平常所指的类,还包括枚举、数组、注解等;
参数化类型,就是我们平常所用到的泛型List、Map;
数组类型,并不是我们工作中所使用的数组String[] 、byte[],而是带有泛型的数组,即T[] ;
基本类型,也就是我们所说的java的基本类型,即int,float,double等
空接口
Type是个空接口,没有定义任何方法,通过多态提高了程序的扩展性,具体实现去看下面的子类;
Type接口下共有4个"儿子",每一个“儿子”代表着Java中的一种类型;
1.ParameterizedType
参数化类型,即泛型;例如:List<T>、Map<K,V>等带有参数化的对象;
以上,简单介绍了Java-Type的体系;为了解决泛型,JDK1.5版本开始引入Type接口;在此之前,Java中只有原始类型,所有的原始类型都是通过Class进行抽象;有了Type以后,Java的数据类型得到了扩展,从原始类型扩展为参数化类型(ParameterizedType)、数组类型(GenericArrayType)、类型变量(TypeVariable);
1.ParameterizedType
在ParameterizedType接口中,有3个方法,分别是getActualTypeArguments()、 getRawType()、 getOwnerType();
如:Map<Integer, String>
Type[] getActualTypeArguments()
: 返回实际泛型类型列表, 如上面那个Map<Integer, String>的实际
泛型数组中有两个元素,第1个是Integer,第2个是
String。
Type getRawType()
: 返回承载该泛型信息的对象, 如上面那个Map<Integer, String>
承载范型信息的对象是Map
Type getOwnerType()
: 返回是谁的member.(上面那两个最常用)
1.1 getActualTypeArguments
获取泛型中的实际类型,可能会存在多个泛型,例如Map<K,V>,所以会返回Type[]数组
值得注意的是,无论<>中有几层嵌套(List<Map<String,Integer>),getActualTypeArguments()方法永远都是脱去最外层的<>(也就是List<>),将尖括号内的内容(Map<String,Integer>)返回;
我们经常遇到的List<T>,通过getActualTypeArguments()方法,得到的返回值是TypeVariableImpl对象,也就是TypeVariable类型(后面介绍);
1.2 getRawType
获取声明泛型的类或者接口,也就是泛型中<>前面的那个值
1.3 getOwnerType
通过方法的名称,我们大概了解到,此方法是获取泛型的拥有者,那么拥有者是个什么意思?
Returns a {@code Type} object representing the type that this type
* is a member of. For example, if this type is {@code O.I}, return a representation of {@code O}. (摘自JDK注释)
通过注解,我们得知,“拥有者”表示的含义--内部类的“父类”,通过getOwnerType()方法可以获取到内部类的“拥有者”;例如: Map 就是 Map.Entry<String,String>的拥有者;
资料源自互联网,经综合整理而成,若有侵犯,请联系作者。