zoukankan      html  css  js  c++  java
  • 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;>;>; )。

  • 相关阅读:
    linux命令行打印图片
    linux 命令行打印二维码
    ReactNative DeviceEventEmitter
    python操作Excel的几种方式
    python 爬虫实例(二)
    各种软件安装的URL
    python 爬虫实例(一)
    eclipse的maven中需要把jar的包文件登入到自己的仓库里面的操作
    关于Maven项目build时出现No compiler is provided in this environment的处理
    eclipse和maven生成web项目的war包的操作方法
  • 原文地址:https://www.cnblogs.com/niceboat/p/9478976.html
Copyright © 2011-2022 走看看