【问题标题】:how to use generic type in gson typeToken?如何在 gson typeToken 中使用泛型类型?
【发布时间】:2020-04-28 07:57:48
【问题描述】:

我想在 gson TypeToken 中使用泛型类型,像这样:

public static <T> T execute(String s) throws SecurityException {
    return new Gson().fromJson(s, new TypeToken<T>(){}.getType());
}

public static void main(String[] args) {
    String s = "[{\"username\": \"abc\", \"password\": \"abc\"}, {\"username\": \"abc1\", \"password\": \"abc1\"}]";

    List<Auth> a1 = new Gson().fromJson(s, new TypeToken<List<Auth>>(){}.getType());
    System.out.println(a1);
    System.out.println("a1 class: " + a1.get(0).getClass());

    List<Auth> a2 = TypeClass.execute(s);
    System.out.println(a2);
    System.out.println("a2 class: " + a2.get(0).getClass());
}

static class Auth {
    private String username;
    private String password;
}

但它会抛出异常:

[cn.gitbug.test.TypeClass$Auth@7921b0a2, cn.gitbug.test.TypeClass$Auth@174d20a]
a1 class: class cn.gitbug.test.TypeClass$Auth
[{username=abc, password=abc}, {username=abc1, password=abc1}]
Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to cn.gitbug.test.TypeClass$Auth
    at cn.gitbug.test.TypeClass.main(TypeClass.java:22)

那么我该如何编写execute() 方法呢?

【问题讨论】:

    标签: generics serialization gson typetoken


    【解决方案1】:
    public static <T> T execute(String s) throws SecurityException {
        return new Gson().fromJson(s, new TypeToken<T>(){}.getType());
    }
    

    这不起作用,因为T 未绑定,因此擦除类型为Object(反序列化为Map)。

    Gson 文档中的示例和上面的代码有效,因为泛型类型参数在编译时是已知的,因此该类将具有预期的擦除类型:

    new TypeToken<List<Auth>>(){}.getType()
    

    Gson 2.8.0(2016 年发布)添加了TypeToken.getParameterized(...)。这允许您为泛型类动态创建TypeTokens,但您仍然必须手动指定泛型类型参数。

    接受 JSON 字符串作为唯一参数(如您的 execute)然后自行确定类型的方法是不可能的,因为有关泛型类型参数 T 的信息在运行时不可用。

    【讨论】:

      【解决方案2】:

      我的解决方案建议

      public static <T> List<T> execute(String json, Class<T> clazz) {
          Type type = TypeToken.getParameterized(List.class,clazz).getType();
          return new Gson().fromJson(json, type);
      }
      

      并使用

      List<Auth> auths = deserialize(json, Auth.class);
      

      更多关于linklink

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多