java中获取泛型参数详解【全网最详细】

java中所有的类型都继承自Type其中包括Class类也是继承自它,另外它还有四个重要的子类

  1. ParameterizedType表示是个带泛型的类型,如List<String>List<T>,通过该类型的getActualTypeArguments()方法可获取到下面三个类型,也有可能获取到Class类型
  2. GenericArrayType表示是个泛型数组,如List<String>[]List<T>[]
  3. TypeVariable表示泛型变量,如public <T> void method(T t)中的 T
  4. WildcardType表示通配符,如public void method(List<?> arg)中的 ?
    ParameterizedType示例
    方法签名如下所示
public <T> void genericMethod(List<T> arg1, List<T[]> arg2,
                                  String arg3, Son1 arg4,
                                  Parent arg5, Parent<?> arg6,
                                  Parent<?>[] arg7) {

}

static class Parent<T> {

}

static class Son1 extends Parent<String> {

}

如果调用MethodgetGenericParameterTypes()可获取到带泛型的参数

  1. arg1是ParameterizedType,如果调用该类型的getActualTypeArguments()即可获取到T它的类型是TypeVariable类型
  2. arg2是ParameterizedType,如果调用该类型的getActualTypeArguments()即可获取到T[]它的类型是GenericArrayType类型
  3. arg3是Class类型
  4. arg4是Class类型
  5. arg5是Class类型
  6. arg6是ParameterizedType类型,如果调用该类型的getActualTypeArguments()即可获取到?它的类型是WildcardType类型
  7. arg7是GenericArrayType类型,如果调用该类型的getGenericComponentType()即可获取到ParameterizedType因为getGenericComponentType()返回的是数组的实际类型,而arg7的实际类型也是一个泛型参数

注意点

在使用的时候应注意局部变量是获取不到泛型的类型的,对于类来说只能获取其父类的泛型类型,而不能获取本类的泛型参数

List<String> arr = new ArrayList<>();
System.out.println(arr.getClass().getGenericSuperclass());
对于上面的代码,由于arr是局部变量,所以是获取不到泛型中的String的,而ClassgetGenericSuperclass()方法也只能获取父类的泛型参数,对于上面这个代码获取到的类型是java.util.AbstractList<E>它的类型是ParameterizedType

对于前面ParameterizedType示例中代码的Son1类来说,可以获取到其指定的泛型类型String获取的方法也很简单System.out.println(((ParameterizedType) Son1.class.getGenericSuperclass()).getActualTypeArguments()[0])因为我们已知在子类继承父类时指定了泛型,所以其类型就是ParameterizedType,那为什么不能是其他三个呢?

为什么不能是GenericArrayType

比如GenericArrayType为什么不能是它?如果你有这个疑惑那肯定是没能理解什么情况下才是那个类型,我们说只有当这个参数是个数组时才是这个类型, 很明显我们子类继承父类的时候不能继承一个数组,这里给出两个示例,一个正确的,一个错误的

这是正确的,我们继承自List,其里面的泛型指定为String[]数组,但是请注意,这种泛型的类型为ParameterizedType而不是GenericArrayType,因为GenericArrayType的格式是List<String>[]这样才是GenericArrayType类型

public class Son extends List<String[]> {}

如果java支持这中形式的继承的话那它的类型应该是GenericArrayType但是java不支持,这种一种语法错误

public class Son extends List<String>[] {}
为什么不能是TypeVariable

那为什么不能是TypeVariable?其实也很简单,TypeVariable类型代表的是泛型本身,如:public <T> void method(T t){}中的 T,那我们继承的时候能继承自泛型吗? 比如 public class Son<T> extends T {} 很明显也是错误的

为什么不能是WildcardType

有了上面两个案例,相信你这里应该很清楚了,WildcardType表示的是一种通配符,比如public void method(List<?> arag1){}中的 ?类继承的时候能继承自通配符?吗?很显然不能

所以最后的结论就是如果调用类的getGenericSuperclass()方法其返回的类型一定是Class类型,或者是ParameterizedType关键就是看继承父类时有没有指定泛型,如果有指定泛型则是ParameterizedType类型,如果没有则是Class类型

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值