【问题标题】:Java Gson Serialize and Deserialize object inside HashMap(key, Object) [duplicate]HashMap(key,Object)中的Java Gson序列化和反序列化对象[重复]
【发布时间】:2016-08-20 13:42:11
【问题描述】:

我有以下代码作为我想要实现的示例:

public static void main(String args[]) {

    Map<String, Object> map = new HashMap<String, Object>();
    map.put("1", new A());  
    map.put("2", new B());
    String json = new Gson().toJson(map);
    Type type = new TypeToken<Map<String, Object>>(){}.getType();
    map = new Gson().fromJson(json, type);
    A a = (A) map.get("1"); 
    B b = (B) map.get("2");

}

static class A {

    int inum = 1;
    double dnum = 1.0;
    String str = "1";

}

static class B {

    int inum = 2;
    double dnum = 2.0;
    String str = "2";

}

以下代码导致此异常:

Exception in thread "main" java.lang.ClassCastException: com.google.gson.internal.LinkedTreeMap cannot be cast to ParseJson$A
    at ParseJson.main(ParseJson.java:19)

所以问题是: 如何在被 Gson 序列化和反序列化的通用 HashMap 中获取正确的实例?

【问题讨论】:

  • 使用类型标记。将副本应用到 Map 而不是 List

标签: java json casting hashmap


【解决方案1】:

Object 被反序列化为com.google.gson.internal.LinkedTreeMap,所以告诉Gson 你想要A 类。

public static void main(String args[]) {
    Map<String, Object> map = new HashMap<>();
    map.put("1", new A());
    String json = new Gson().toJson(map);
    Type type = new TypeToken<Map<String, A>>() {
    }.getType();
    map = new Gson().fromJson(json, type);
    A a = (A) map.get("1");
    System.out.println(a.str);
}

static class A {
    private int num1 = 1;
    private double num2 = 2.0;
    private String str = "String";
}

希望对你有帮助。

更新

基类(在这种情况下为X)可能是一个解决方案:

public static void main(String args[]) {
    Map<String, Object> map = new HashMap<String, Object>();
    map.put("1", new A());
    map.put("2", new B());
    String json = new Gson().toJson(map);
    Type type = new TypeToken<Map<String, X>>(){}.getType();
    map = new Gson().fromJson(json, type);
    X a = (X) map.get("1");
    X b = (X) map.get("2");
    System.out.println(a.str);
    System.out.println(b.str);
}

static class X {
    int inum;
    double dnum;
    String str;

    X() {
    }
}

static class A extends X {
    A() {
        inum = 1;
        dnum = 1.0;
        str = "1";
    }
}

static class B extends X {
    B() {
        inum = 2;
        dnum = 2.0;
        str = "2";
    }
}

【讨论】:

  • 您的回答是正确的,但我实际上是在尝试实现一些更复杂的东西。我更新了问题主体以进行说明。我用 Object 定义 HashMap 是有原因的。因为我需要包含不同的类型。谢谢!
  • 看来我再次过度简化了我的情况:) 尽管在我给出的情况下你的答案再次正确。在我的真实案例中,这些类之间没有真正的相似性(可以是字符串、枚举或任何其他类..)但我开始认为没有优雅的解决方案。我现在正在做的只是将 valueOf 用于变量,这些变量被解释为原始的可解释类型。但是对于复杂的类,我没有解决方案,所以我只是将它们的字段分开并分别传递......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-08
  • 1970-01-01
相关资源
最近更新 更多