【问题标题】:How to Parse Json generic array with inheritance items如何使用继承项解析 Json 泛型数组
【发布时间】:2020-02-14 13:39:11
【问题描述】:

我的问题不一样是this question。 如果我想解释一下,假设我们有这些类(A、B、C)。

@Data
@NoArgsConstructor
class A {
    private Integer x;
    private String type;

    public A(String type, Integer x) {
        this.type = type;
        this.x = x;
    }
}
@Data
class B extends A {
    private Integer y;

    public B(Integer x, Integer y) {
        super("B", x);
        this.y = y;
    }
}
@Data
class C extends A {
    private Integer z;

    public C(Integer x, Integer z) {
        super("C", x);
        this.z = z;
    }
}

知道我想解析其基类为 A 的数组,并且使用名为 type 的属性,我想将每个项目转换为其特定的类。 类似这样的代码。

public static void main(String[] args) {
        Gson gson = new Gson();
        List<A> list = new ArrayList<>();
        A a = new A("A", 0);
        list.add(a);
        B b = new B(1, 2);
        list.add(b);
        C c = new C(3, 4);
        list.add(c);
        String serializedJson = gson.toJson(list);
        List<? extends A> deserializedList = gson.fromJson(serializedJson, new TypeToken<List<? extends A>>() {
        }.getType());
        for (A item : deserializedList) {
            System.out.println(item.getType());
            if (item instanceof B) {
                System.out.println(((B) item).getY());

            } else if (item instanceof C) {
                System.out.println(((C) item).getZ());

            }
        }
    }

序列化的json是这样的

[{"x":0,"type":"A"},{"y":2,"x":1,"type":"B"},{"z":4,"x":3,"type":"C"}]

在现实世界中,我有类似这样的 json 并且想要解析它。 但是当我运行代码时 y 和 z 属性未打印并且对象不是 B 或 C 的实例。 如何实现这个目标来解析和创建每个带有类型属性的项目。

【问题讨论】:

  • 这不是因为您将list 定义为List&lt;A&gt; - 而不是List&lt;? extends A&gt; 之类的东西吗?
  • 我还要说,因为您已经尝试使用 type 属性标记类,您应该能够使用 A["type"] 或类似的东西以及 instanceof 的东西 -甚至可能是 A.type - 不确定 Gson 是如何工作的。

标签: java json gson deserialization


【解决方案1】:

我通过 Gson TypeAdapterFactory 机制找到了解决方案。 创建一个类来实现 com.google.gson.TypeAdapterFactory。有关更多详细信息,请参阅link

【讨论】:

    【解决方案2】:
    for(A item : deserializedList) {
      switch(item.getType()) {
        case "B":
          System.out.println(((B) item).getY());
        break;
        case "C":
          System.out.println(((C) item).getZ());
        break;
      }
    }
    

    【讨论】:

    • 不工作。 java.lang.ClassCastException !当我们的对象不是 B 或 C 的实例时,绝对会发生此异常!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多