问题描述
我创建了一个封装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.toString());
return result;
}
}
我在反序列化方面遇到问题(方法convertToString)。这行代码:T result = gson.fromJson(jsonString,type);在编译时抛出此错误:
“无法确定T的类型参数;对于具有上限T,java.lang.Object的类型变量T,不存在唯一的最大实例”
我了解这意味着代码太模糊且不安全。在此版本之前,我传递了名为 object 的参数而不是变量 type 的参数,但问题是返回的对象有问题,并在代码执行后抛出NullPointerException。我读了有关Gson和泛型类型的问题的书,所以我进入了实际版本。
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]]
旁注:
-
您的实用程序类名为
JsonParser
,它与同名from GSON lib的类冲突-可能造成不必要的混乱 -
您将json字符串反序列化为对象的方法名为
convertToString
,但它的作用恰恰相反 -
泛型类型参数
<T extends Object>
没有多大意义,java中的每个对象实例都扩展了Object,因此它可能只是<T>