java - 如何用 gson 处理泛型类型?
问题描述
我创建了一个封装 gson 序列化/反序列化行为的类。这个想法是使这个类完全通用,所以它可以被需要它的软件的任何部分使用。
public class JsonParser {
private static final Logger log = Logger.getLogger(JsonParser.class.getName());
private static final Gson gson = new Gson();
public static String convertToJson(Object object) {
String result = gson.toJson(object);
log.log(Level.INFO, "Result: {0}", result);
return result;
}
public static <T extends Object> T convertToString(String jsonString, Class<T> object) {
Type type = new TypeToken<T>() {}.getType();
T result = gson.fromJson(jsonString, type);
log.log(Level.INFO, "Result: {0}", result.toString());
return result;
}
}
我在反序列化(方法 convertToString)中遇到问题。该行: T 结果 = gson.fromJson(jsonString, type); 在编译时抛出此错误:
“无法确定 T 的类型参数;类型变量 T 的上限为 T,java.lang.Object 不存在唯一的最大实例”
我理解这意味着代码在简历中过于模糊和不安全。在此版本之前,我传递的是名为object而不是变量类型的参数,但问题是返回的对象有问题,并在稍后的代码执行中抛出 NullPointerException。我阅读了有关 Gson 和 Generic Types 的问题,所以我进入了实际版本。
以防万一,这是对有问题的方法的调用(响应是一个字符串):
JsonParser.convertToString(response, Response.class);
所以问题是:我怎样才能使这个编译并保持我的方法在意图中通用?
解决方案
不要在您的实用程序方法中创建类型标记:
Type type = new TypeToken<T>() {}.getType();
让调用者为您创建它:
public static <T> T convertToString(String jsonString, TypeToken<T> typeToken)
T result = gson.fromJson(jsonString, typeToken.getType());
log.log(Level.INFO, "Result: {0}", result.toString());
return result;
}
例子:
class Pojo {
private String field1;
private int field2;
@Override
public String toString() {
return "Pojo [field1=" + field1 + ", field2=" + field2 + "]";
}
}
List<Pojo> list = convertToString("[{\"field1\":\"abc\", \"field2\" : 10}]", new TypeToken<List<Pojo>>() {});
assert list.size() == 1;
assert list.get(0).field1.equals("abc");
assert list.get(0).field2 == 10;
输出
INFO: Result: [Pojo [field1=abc, field2=10]]
旁注:
您的实用程序类被命名,它与GSON lib
JsonParser
中具有相同名称的类发生冲突- 这可能会造成不必要的混淆您将 json 字符串反序列化为对象的方法已命名
convertToString
,但它的作用完全相反泛型类型参数
<T extends Object>
没有多大意义,java中的每个对象实例都扩展了Object,所以它可能只是<T>
推荐阅读
- apache-poi - 我想通过迭代行在 Excel 工作表中编写一组随机数。我可以编写随机数,但无法将它们存储在 excel 中
- node.js - BigQuery - 如何对结果进行分页
- amazon-web-services - 运行 aws_s3 playbook 时“错误!'aws_s3' 不是 Play 的有效属性”
- session - PHP 7 使用所需的会话 ID 重新生成会话
- python - 如何在二维数组中存储字符串和坐标?
- c# - IConfiguration.GetSection() 作为属性返回 null
- go - 从大文本中删除所有非字母数字字符的有效方法
- laravel - 在ajax需要加载一个字段值并使用范围值创建一个select_from_array之后
- vue.js - Highcharts-vue:带有向下钻取的堆叠列
- scala - 如何获取集群的最小值和最大值