generics - 如何在 gson typeToken 中使用泛型类型?
问题描述
我想在 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()
方法呢?
解决方案
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(...)
。这允许您TypeToken
为泛型类动态创建 s,但您仍然必须手动指定泛型类型参数。
接受 JSON 字符串作为唯一参数(如您的execute
)然后自行确定类型的方法是不可能的,因为有关泛型类型参数T
的信息在运行时不可用。
推荐阅读
- java - 在典型的微服务架构中,如何链接各个微服务的独立 RDBMS 数据库中的相关数据?
- docker - 如何创建包含公共和私有图像的 docker-compose.yml 文件?
- python - multiprocessing.Queue 不能用作类中的实例变量?
- scikit-learn - 他们是否有任何 sklearn 模块,例如用于回归的投票分类器?
- c++ - 当函数中没有声明具有相同名称的对象时发生阴影
- c# - 如何使用 C# 将元素插入到格式不正确的 XML 文件中的特定节点中?
- generics - Kotlin 可扩展的空值检查
- limit - 在 mikrotik/hotspot 和 freeradius mikroik-group 属性中使用用户配置文件控制用户组带宽限制
- influxdb - 如何在 influx db 中获取字段值的分布
- json - 如果键名与“名称”匹配,则使用 jq 提取键值