Java之泛型ParameterizedType、getGenericSuperclass、getActualTypeArguments

在反射中,我们经常遇到这样代码: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>的拥有者;

 

资料源自互联网,经综合整理而成,若有侵犯,请联系作者。

  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值