如何在文件中写入非序列化对象(例如 Shapes)以便稍后读取它们

How to write non-serialized objects, such as Shapes, in a file so they can then be read later

我有一个程序 class 类似于下面的基本示例:

public class Vertex extends Circle implements Serializable {
    private int vertexID;
    private final static double SIZE = 10.0;

    // Constructor
    public Vertex(int ID, double x, double y) {
        super(x, y, SIZE, Color.BLUE);
        this.vertexID = ID;
    }
}

我想做的是使用 ObjectOutputStreamList<Vertex> myVertices 写入文件,这要求每个 class 实现 Serializable界面。示例如下:

FileChooser fc = new FileChooser();
File fileChosen = fc.showOpenDialog(window);

try {               
   FileOutputStream fOutStream = new FileOutputStream(fileChosen);
   ObjectOutputStream oOutStream = new ObjectOutputStream(fOutStream);

   oOutStream.writeObject(myVertices);
   oOutStream.close();
} catch {
    // Exception handling here
}

上面实现的问题在于,虽然Vertex实现了Serializable,但是超级classCircle和它的超级classShape 不执行 Serializable。结果是该文件包含 Vertex 个对象,但所有 Shape 详细信息都丢失并默认为 0。

有没有解决这类问题的简单方法?我目前唯一的选择似乎是创建我自己的 Shape/Circle,将 location/display 数据存储为双精度数据,这样它就可以成为 Serializable。显然,对于一个 class 来说,这并不太费力,但我还有一些其他 Shape 对象也想保存。我假设,然后必须构造实际的 Shape 对象来显示它们。

谢谢!

您需要创建一个 writeObject/readObject 方法来保存您需要的附加状态。

Serialization - readObject writeObject overrides

Uses of readObject/writeObject in Serialization

Why are readObject and writeObject private, and why would I write transient variables explicitly?

Java Custom Serialization

Java: efficiency of writeObject vs writeExternal

如果有人想查看 Shape 的实际代码,特别是 Circle 对象,这里是我根据已接受的答案实现的代码。还包括 List<Vertex> myVertices = new ArrayList():

的示例
private void writeObject(ObjectOutputStream oos) throws IOException {
    oos.writeInt(vertexID);
    oos.writeObject(myVertices);
    oos.writeDouble(super.getCenterX());
    oos.writeDouble(super.getCenterY());
}

private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
    // Read in same order as write
    this.vertexID = ois.readInt();
    this.myVertices = (List<Vertex>) ois.readObject();
    super.setCenterX(ois.readDouble());
    super.setCenterY(ois.readDouble());

    // Default Circle properties
    super.setRadius(SIZE); // Default
    super.setFill(Color.BLUE); // Default
}