gpt4 book ai didi

java - 多态数组失败的序列化

转载 作者:行者123 更新时间:2023-12-02 05:00:01 25 4
gpt4 key购买 nike

我通过在基类上添加注释来启用多态序列化支持。我能够成功序列化单个对象,并且它将类型信息写入序列化数据的一部分。但是,如果我将对象存储在列表中并序列化它,则不会发生同样的情况。

这个问题似乎已在 1.6.3 中修复 ( http://jira.codehaus.org/browse/JACKSON-362 )

我正在使用 Jackson 2.3.2,但仍然面临这个问题。

有人知道如何解决这个问题吗?

代码:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY,property = "type")
@JsonSubTypes({@Type(value = Derived.class, name = "derived")})
public abstract class Base {

}

public class Derived extends Base {

private String field;

public String getField() {
return field;
}

public void setField(String field) {
this.field = field;
}

}

public class Test {

public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
Derived d = new Derived();
d.setField("Name");
Base b = d;
System.out.println(mapper.writeValueAsString(b));
List<Base> list = new ArrayList<Base>();
list.add(d);
System.out.println(mapper.writeValueAsString(list));
}
}

输出:
{“类型”:“派生”,“字段”:“名称”}
[{"field":"Name"}]

谢谢,
普拉文

最佳答案

答案在https://github.com/FasterXML/jackson-databind/issues/699

这是由于 Java 类型删除:当序列化 List 时,Jackson 所看到的所有类型都是 List(大致相当于 List)。并且由于类型 Object 没有多态类型信息(注释),因此不会写入任何内容。所以这不是 Jackson 的 bug,而是 Java Type Erasure 的一个不幸的特性。它不适用于数组,因为它们保留元素类型信息(数组不是通用的;不同类型的数组是不同的类,而通用类型主要是编译时语法糖)。

解决这个问题主要有以下三种方法:

pass full generic type using TypeReference (ObjectMapper has method like mapper.writerFor(new TypeReference<List<Base>>() { }).writeValue(....)
Sub-class List to something like public class BaseList extends ArrayList<Base>() { }, and pass that: this type WILL retain type information
Avoid using root-level List and Maps

我个人建议执行(3),因为这可以避免与类型删除相关的所有问题。在我看来,JSON 根值应该始终是 JSON 对象,通常序列化到 POJO 或从 POJO 序列化。

不过,方法 (2) 是可行的,而且大多数用户都是这么做的。它确实需要使用额外的帮助器类。

方法(1)可能有效,也可能无效;问题是强制类型信息也会影响实际值序列化。因此虽然它会添加类型id,但可能会导致某些属性没有被序列化。

关于java - 多态数组失败的序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28369389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com