【问题标题】:Gson type token issue with generic deserialization通用反序列化的 Gson 类型令牌问题
【发布时间】:2015-07-16 18:41:06
【问题描述】:

我发现了很多类似的问题,但没有一个有帮助。

这行得通:

public class Assets<T> {

public T getAndDeserializeAsset(String endpoint, String assetId, Client client){
    Response response = client.get(endpoint+assetId);
    Gson gson = new Gson();
    T asset = gson.fromJson(response.body, new TypeToken<Email>(){}.getType());
    return asset;
}

}

这不是:

public class Assets<T> {

public T getAndDeserializeAsset(String endpoint, String assetId, Client client){
    Response response = client.get(endpoint+assetId);
    Gson gson = new Gson();
    T asset = gson.fromJson(response.body, new TypeToken<T>(){}.getType());
    return asset;
}

}

我是按照官方文档做的,所以不知道为什么不行。

错误:

Exception in thread "main" java.lang.ClassCastException: com.rest.api.Response cannot be cast to model.Email
at main.Main.main(Main.java:34)

【问题讨论】:

    标签: java generics gson


    【解决方案1】:

    唯一有意义的是Assets&lt;T&gt; 的实例必须是Assets&lt;Response&gt; 的实例,而不是Assets&lt;Email&gt; 的实例。您确定您的 Assets 实例是正确的类型吗?

    另外,请记住 Gson 不是协变的;当您使用TypeToken 指定类型时,您必须使用您希望反序列化到的确切类型。例如,如果您使用类定义:

    class Email extends Response {
    

    然后使用:

    new Assets<Response>();
    

    因为 Gson 不是协变的,所以无法知道您真正想要的是 Email

    【讨论】:

      【解决方案2】:

      上述代码未能将 value 解释为类型,因为 Gson 调用 Assets.getClass() 来获取其类信息,但此方法返回一个原始类 Assets.class。这意味着 Gson 无法知道这是 Assets 类型的对象,而不仅仅是普通的 Assets。

      您可以通过为泛型类型指定正确的参数化类型来解决此问题。您可以使用 TypeToken 类来做到这一点。

      Type AssetsType = new TypeToken<Assets<Example>>() {}.getType();
      gson.toJson(assets, AssetsType );
      gson.fromJson(json, AssetsType );
      

      更多信息请查看gson-user-guide

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-02-03
        • 1970-01-01
        • 2015-07-07
        • 1970-01-01
        • 2013-08-26
        相关资源
        最近更新 更多