最近正好使用到了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;>;>; )。

TypeToken获取运行时泛型类型的更多相关文章

  1. java 面向对象(四十一):反射(五)反射应用二:获取运行时类的完整结构

    我们可以通过反射,获取对应的运行时类中所有的属性.方法.构造器.父类.接口.父类的泛型.包.注解.异常等....典型代码: @Test public void test1(){ Class clazz ...

  2. 【转】Java Web 项目获取运行时路径 classpath

    Java Web 项目获取运行时路径 classpath 假设资源文件放在maven工程的 src/main/resources 资源文件夹下,源码文件放在 src/main/java/下, 那么ja ...

  3. Javascript 笔记与总结(2-9)获取运行时的 style 对象

    获取内存中(正在渲染)的 style 的值(非内联 style,obj.style 只能获得内联 style 的值),可以用 obj.currentStyle(低版本 IE 和 Opera 支持)和 ...

  4. 日志系统实战(二)-AOP动态获取运行时数据

    介绍 这篇距上一篇已经拖3个月之久了,批评自己下. 通过上篇介绍了解如何利用mono反射代码,可以拿出编译好的静态数据.例如方法参数信息之类的. 但实际情况是往往需要的是运行时的数据,就是用户输入等外 ...

  5. Java Web 项目获取运行时路径 classpath

    假设资源文件放在maven工程的 src/main/resources 资源文件夹下,源码文件放在 src/main/java/下, 那么java文件夹和resources文件夹在运行时就是class ...

  6. 使用Mono Cecil 动态获取运行时数据 (Atribute形式 进行注入 用于写Log) [此文报考 xxx is declared in another module and needs to be imported的解决方法]-摘自网络

    目录 一:普通写法 二:注入定义 三:Weave函数 四:参数构造 五:业务编写 六:注入调用 7.  怎么调用别的程序集的方法示例 8. [is declared in another module ...

  7. Android6.0获取运行时权限

    照着<第一行代码>打代码,然并卵,感叹技术进步的神速.最后提醒一点:IT类的书籍一定要注意出版时间!出版时间!出版时间!重要的事情说三遍 问题出在android6.0的权限获取问题上,以前 ...

  8. Java进阶(四)Java反射TypeToken解决泛型运行时类型擦除问题

    在开发时,遇到了下面这条语句,不懂,然习之. private List<MyZhuiHaoDetailModel> listLottery = new ArrayList<MyZhu ...

  9. Java中获取类的运行时结构

    获取运行时类的完整结构 通过反射获取运行时类的完整结构 Field(属性).Method(方法).Constructor(构造器).Superclass(父类).Interface(接口).Annot ...

随机推荐

  1. 2018.5.11 Java利用反射实现对象克隆

    package com.lanqiao.demo; /** * 创建人 * @author qichunlin * */ public class Person { private int id; p ...

  2. 4G 内存 怎么只有2.99G可用

    32为系统只可以识别3.25G,而且有256M的内存被显卡共享显存了,所以只剩2,99G.

  3. js菜鸟备忘

    1.图片切换 function changeImage() { var img = document.getElementById("myImg"); ")) img.s ...

  4. python中的sort、sorted排序

    我们通常会遇到对数据库中的数据进行排序的问题,今天学习一下对列表和字典的排序方法. 列表 第一种:内建方法sort sort()对列表排序是永久性的排序. 用法:sort(*, key=None, r ...

  5. C#基础-判断语句

    switch语句 Console.WriteLine("请输入月份"); string strInput = Console.ReadLine(); switch(strInput ...

  6. 设置mysql允许外部连接访问

    错误信息: SQL Error (1130): Host ‘192.168.1.88’ is not allowed to connect to this MySQL server 说明所连接的用户帐 ...

  7. 配置wamp开发环境

    新手在PHP网站建设时,会使用使用PHP的集成开发环境,这样利于开发和理解!但是做为一个网站开发人员,会独立的配置开发环境这是必须的……因为集成的环境毕竟是固定的,不利于自己的开发.好,废话少说咱现在 ...

  8. java代码导出数据到Excel、js导出数据到Excel(三)

     jsp内容忽略,仅写个出发按钮:          <button style="width: 100px" onclick="expertExcel()&quo ...

  9. Altium Designer入门学习笔记4:PCB设计中各层的含义

    阻焊层:solder mask,是指板子上要上绿油的部分:因为它是负片输出,所以实际上有solder mask的部分实际效果并不上绿油,而是镀锡,呈银白色! 助焊层:paste mask,是机器贴片时 ...

  10. LeetCode(290) Word Pattern

    题目 Given a pattern and a string str, find if str follows the same pattern. Here follow means a full ...