TypeToken获取运行时泛型类型

 

最近正好使用到了Guava的TypeToken来获取泛型的类型信息

 

比如,泛型父类需要获取其子类定义的泛型类型时:

public abstract class GenericClazz<V> {
  
  private Class<V> classType;
  
  public void doSth() {
    final TypeToken<V> typeToken = new TypeToken<V>(getClass()) {};
    classType = (Class<V>) typeToken.getRawType();  //获得子类的泛型类型
  }
}

 

而使用反射,就稍微复杂了一点。

public abstract class ReflectClazz<V> {
  
  private Class<V> classType;
  
  public void doSth() {
    final Type genType = getClass().getGenericSuperclass();
    classType = (Class<V>) ((ParameterizedType) genType).getActualTypeArguments()[0];  //获得子类的泛型类型
  }
}

而当继承类申明的泛型V也是个泛型类,如 public class SubClazz extends ReflectClazz<Map<Integer, String>> {} 这种,使用反射就会更加繁琐……

 

 

还有一种情况,当我们需要在方法/局部变量中获取泛型类型时,也可以使用TypeToken:

  public void getGenericType() {
    final TypeToken typeToken = new TypeToken<List<Integer>>() {};
    final Type type = typeToken.getType(); //java.util.List<java.lang.Integer>
  }

上面使用TypeToken的目的是为了在运行时获取List<T>的泛型类型Integer,反射则办不到。

(类型擦除机制,.class的LocalVariableTable属性中只会保留Ljava/util/ArrayList,不会是 Ljava/util/ArrayList<Ljava/lang/Integer;> )

 

TypeToken则不是直接利用反射,而是曲线救国:创建一个TypeToken<T>的匿名继承类。由于匿名类的申明信息中保留了泛型信息,通过反射可得…

(编译器不会擦除声明信息,Signatur属性中会保存该匿名类的完整信息,如 Lcom/google/common/reflect/TypeToken<Ljava/util/List<Ljava/lang/Integer;>;>; )。

 

转载于:https://www.cnblogs.com/niceboat/p/9478976.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值