使用 gson 反序列化时将 TypeToken 转换为 Type 时出错

Posted

技术标签:

【中文标题】使用 gson 反序列化时将 TypeToken 转换为 Type 时出错【英文标题】:Error casting TypeToken to Type when deserializing with gson 【发布时间】:2012-07-14 06:21:44 【问题描述】:

我有一个类可以使用此函数反序列化泛型的 ArrayList,正如该线程的第一个答案中所述:Java abstract class function generic Type

public <T> ArrayList<T> arrayType(String data)
    return g.fromJson(data,   TypeToken.get(new ArrayList<T>().getClass()));

Eclipse 要求我转换 TypeToken 导致这个(sinde 函数 fromJson 需要一个类型,而不是一个 TypeToken)

public <T> ArrayList<T> arrayType(String data)
    return g.fromJson(data,  (Type) TypeToken.get(new ArrayList<T>().getClass()));

结果我得到这个错误:

java.lang.ClassCastException: com.google.gson.reflect.TypeToken cannot be cast to java.lang.reflect.Type

gson user manual 他们告诉你这是调用函数的正确方法

Type collectionType = new TypeToken<Collection<Integer>>().getType();
Collection<Integer> ints2 = gson.fromJson(json, collectionType);

我看不出我做错了什么(如果这是一个有效的答案,为什么我会收到这个演员表错误?)

【问题讨论】:

new ArrayList&lt;T&gt;().getClass()ArrayList.class 完全相同 【参考方案1】:

您正在调用TypeToken.get,它返回一个TypeToken - 而不是Type。在您展示的示例中,它使用TypeToken.getType(),它返回Type

所以你可以使用:

return g.fromJson(data, TypeToken.get(new ArrayList<T>().getClass()).getType());

... 这将返回一个Type,但它可能不是你真正想要的。特别是,由于类型擦除,无论您从调用站点指定的T,都会返回相同的类型。如果您希望类型真正反映ArrayList&lt;T&gt;,则需要将类传递给方法,尽管我不完全确定从那里去哪里。 (根据我的经验,Java 反射 API 在泛型方面并不是很清楚。)

顺便说一句,我希望一个名为 arrayType 的方法与 arrays 相关,而不是 ArrayList

【讨论】:

我最终不得不将类型作为参数传递。你给我的解析了我的 JSON,没有任何警告或错误,但最后它并没有让我访问 ArrayList 的每个元素。即使长度正确且 toString() 方法有效,它也无法访问它们。

以上是关于使用 gson 反序列化时将 TypeToken 转换为 Type 时出错的主要内容,如果未能解决你的问题,请参考以下文章

Android:Gson通过借助TypeToken获取泛型参数的类型的方法

Gson反序列化泛型实例

gson的 TypeToken

如何在 Kotlin 中将 TypeToken + 泛型与 Gson 一起使用

Gson教程九(译):强制序列化null值

使用 gson 反序列化反序列化对象的内部对象