美文网首页
泛型,TypeToken(Guava)

泛型,TypeToken(Guava)

作者: byamao1 | 来源:发表于2018-10-29 17:27 被阅读0次

众所周知,Java的泛型在运行时会有类型擦除。Guava的TypeToken却很好解决了这个问题。原因在匿名类+反射,其方法getSuperclassTypeParameter获取了Type。其中关键代码是调用了反射方法:

static Type getSuperclassTypeParameter(Class<?> subclass) {
    // 获取泛型超类
    Type superclass = subclass.getGenericSuperclass();
    if (superclass instanceof Class) {
      throw new RuntimeException("Missing type parameter.");
    }
    // 类型参数,这个就是被擦除的泛型类型
    ParameterizedType parameterized = (ParameterizedType) superclass;
    return $Gson$Types.canonicalize(parameterized.getActualTypeArguments()[0]);
 }

其原理就是用一个继承TypeToken的匿名类,从而获取该匿名类的泛型超类,然后将其强制转换为ParameterizedTypeParameterizedType包含了其原始类型ParameterizedType.getRawType()及其泛型类型ParameterizedType.getActualTypeArguments()。举例:
对于List<String>这个类,

List list = new ArrayList<String>(){};
Type superclass = list.getClass().getGenericSuperclass();
ParameterizedType parameterized = (ParameterizedType) superclass;
Type raw = parameterized.getRawType();  // ArrayList类
Type[] types = parameterized.getActualTypeArguments();  // String类

如果是List<List<String>>这种嵌套的泛型,那么还可以对上面Type[] types内的Type继续强制类型转换为ParameterizedType,嵌套获取其内嵌套的泛型。
注意

List list = new ArrayList<String>(){};  //这是匿名类
不要写成
List<String> list = new ArrayList(){}; 
或
List list = new ArrayList<String>();  //这样不是继承,无法获取泛型

TypeLiteral可以通过TypeLiteral.getType()转换为Type,以便gson反序列化。也可以用比较原始的方式:

    // 改造自 TypeToken.getSuperclassTypeParameter()
    static Type getSuperclassTypeParameter(Class<?> subclass) {
        Type superclass = subclass.getGenericSuperclass();
        if (superclass instanceof Class) {
            throw new RuntimeException("Missing type parameter.");
        }
        ParameterizedType parameterized = (ParameterizedType) superclass;
        return parameterized.getActualTypeArguments()[0];
    }

TypeLiteral typeLiteral = new TypeLiteral<List<String>>() {};
Type type = getSuperclassTypeParameter(typeLiteral.getClass());
// gson反序列化
List<String> list = gson.fromJson(json, type);  

相关文章

网友评论

      本文标题:泛型,TypeToken(Guava)

      本文链接:https://www.haomeiwen.com/subject/iuybtqtx.html