如何解决使用循环引用序列化对象
import java.util.List;
public class Stop {
/**
* lines operating this stop
*/
public List<Line> lines;
public String label;
public Stop(String label,List<Line> lines) {
this.label = label;
this.lines = lines;
}
public String getLabel() {
return label;
}
public List<Line> getLines() {
return lines;
}
@Override
public String toString() {
return "Stop{" +
"label='" + label + '\'' +
'}';
}
}
和一个象征公交线路的类:
import java.util.ArrayList;
import java.util.List;
public class Line {
public String label;
public int id;
public List<Stop> stops;
public Line(String label,int id,List<Stop> stops) {
this.label = label;
this.id = id;
this.stops = stops;
}
public Line(String label,int id) {
this(label,id,new ArrayList<>());
System.out.println("used second constructor");
}
public String getLabel() {
return label;
}
public int getId() {
return id;
}
public List<Stop> getStops() {
return stops;
}
@Override
public String toString() {
return "Line{" +
"label='" + label + '\'' +
",id=" + id +
",stops=" + stops +
'}';
}
}
我不想使用 java.beans.XMLEncoder 序列化这些,然后使用 XMLDecoder 反序列化。
在这种情况下(当行持有对其停止的引用时,反之亦然),反序列化失败。解码器忽略带有附加 Line
参数的 List<Stop> stops
构造函数并使用 Line(String label,int id)
构造函数,留下以下消息:
java.lang.IllegalStateException: Could not add argument to evaluated element
Continuing ...
当我完全删除类 Stop
中的操作行列表时,反序列化工作完美。
我做错了什么?
主类:
import java.beans.DefaultPersistenceDelegate;
import java.beans.XMLDecoder;
import java.beans.XMLEncoder;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
public class App {
public static void main(String[] args) {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (XMLEncoder encoder = new XMLEncoder(baos)) {
encoder.setPersistenceDelegate(Line.class,new DefaultPersistenceDelegate(new String[] {"label","id","stops"}));
encoder.setPersistenceDelegate(Stop.class,"lines"}));
ArrayList<Stop> stops = new ArrayList<>();
stops.add(new Stop("Porte Maillot",new ArrayList<>()));
stops.add(new Stop("Auber",new ArrayList<>()));
Line line = new Line("A",stops);
stops.get(0).lines.add(line);
stops.get(1).lines.add(line);
encoder.writeObject(line);
}
System.out.println("xml:");
System.out.println(baos);
try (XMLDecoder decoder = new XMLDecoder(new ByteArrayInputStream(baos.toByteArray()))){
Line line = (Line) decoder.readobject();
System.out.printf("line: %s\n",line);
}
}
}
控制台输出:
xml:
<?xml version="1.0" encoding="UTF-8"?>
<java version="15.0.1" class="java.beans.XMLDecoder">
<object class="Line" id="Line0">
<string>A</string>
<int>0</int>
<object class="java.util.ArrayList">
<void method="add">
<object class="Stop">
<string>Porte Maillot</string>
<object class="java.util.ArrayList">
<void method="add">
<object idref="Line0"/>
</void>
</object>
</object>
</void>
<void method="add">
<object class="Stop">
<string>Auber</string>
<object class="java.util.ArrayList">
<void method="add">
<object idref="Line0"/>
</void>
</object>
</object>
</void>
</object>
</object>
</java>
used second constructor
java.lang.IllegalStateException: Could not add argument to evaluated element
Continuing ...
line: Line{label='A',id=0,stops=[]}
解决方法
循环引用导致 XMLDecoder 无法处理的循环序列化。将其中一个引用设为瞬态并在反序列化时恢复它们将解决该问题,与使用二进制序列化而不是 xml 序列化相同。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。