尝试将 JSON 反序列化为 Map
public static void main(String[] args) {
JsonObject json = new JsonObject();
json.addProperty("str", "str-value");
json.addProperty("int", 10);
json.addProperty("bool", true);
// "json" now contains {"str":"str-value","int":10,"bool":true}
Type mapType = new TypeToken<Map<String, Object>>() {}.getType();
Gson gson = new Gson();
Map<String, Object> map = gson.fromJson(json, mapType);
String str = (String) map.get("str"); // cannot cast Object to String
str = String.valueOf(map.get("str")); // results in java.lang.Object@1632847
}
最佳答案
技术解答
如果你附上Gson源代码,然后调试程序你就会找到问题的根源。问题似乎在于 Gson 代码。
由于您调用 fromJson() 的值是 Object 类型,因此将使用类 com.google.gson.ObjectNavigator 并进入这部分代码 [~第 113 行]
else if (objTypePair.type == Object.class && isPrimitiveOrString(objectToVisit)) {
visitor.visitPrimitive(objectToVisit); //Target value is the proper value after this call
visitor.getTarget(); //target value is now a blank Object.
其中 visitor 是 JSonObjectDeserializationVisitor 类型,objectToVisit 是您的值,objectTypePair 是它要成为的类型(对象)。
现在,JsonObjectDeserializationVisitor 有一个名为 constructed 的标志,默认设置为 false。因此,当调用 getTarget() 方法时,它会检查构造的标志是否为真,如果不是,它会创建您尝试创建的对象的新实例。因为永远不会设置构造的标志,所以对 getTarget() 的调用返回一个空白对象。
对 getTarget() 的调用在代码中似乎是不必要的,而且似乎是问题的根源。 visitPrimitive 通过将解析后的值放入将被传回的目标变量中来执行适当的操作。这似乎是一个围绕对象类型的错误。
这不是您可以解决的问题,除非您愿意对 Gson 进行自定义构建。我建议将其作为报告提交到 Gson 论坛上。 已经有 one report filed对于 1.5 版
变通
我看到有两种方法可以在短期内解决这个问题。
1) 制作<String, String>
类型的 map ,虽然你丢失了类型,但你仍然可以正确地取回值
2) 首先将值放入一个 bean 类中,然后将其序列化。
public class myObj{
String myStr;
int myInt;
boolean myBool;
//get and set methods
}
public static void main(String args[]){
MyObj o = new MyObj();
o.setMyStr("str-value");
Gson gson = new Gson();
String json = gson.toJson(o);
o = gson.fromJson(json, MyObj.class);
}
两者都违背了你想要做的事情的目的,但我相信在谷歌法庭上修复这个错误。
关于java - Gson 反序列化为 Map 通用类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7503375/