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;>;>; )。

  • 相关阅读:
    [saiku] 系统登录成功后查询Cubes
    216. Combination Sum III
    215. Kth Largest Element in an Array
    214. Shortest Palindrome
    213. House Robber II
    212. Word Search II
    211. Add and Search Word
    210. Course Schedule II
    分硬币问题
    开始学习Python
  • 原文地址:https://www.cnblogs.com/niceboat/p/9478976.html
Copyright © 2011-2022 走看看