Java 自定义序列化

2022-08-31 15:12:11

我有一个对象,其中包含一些要序列化的不可序列化字段。它们来自我无法更改的单独API,因此使它们可序列化不是一种选择。主要问题是位置类。它包含四个可以序列化的东西,我需要,所有int。如何使用读/写对象来创建可以执行如下操作的自定义序列化方法:

// writeObject:
List<Integer> loc = new ArrayList<Integer>();
loc.add(location.x);
loc.add(location.y);
loc.add(location.z);
loc.add(location.uid);
// ... serialization code

// readObject:
List<Integer> loc = deserialize(); // Replace with real deserialization
location = new Location(loc.get(0), loc.get(1), loc.get(2), loc.get(3));
// ... more code

我该怎么做?


答案 1

Java 支持自定义序列化。阅读自定义默认协议部分。

引用:

然而,有一个奇怪而狡猾的解决方案。通过使用序列化机制的内置功能,开发人员可以通过在其类文件中提供两种方法来增强正常过程。这些方法是:

  • private void writeObject(ObjectOutputStream out) 抛出 IOException;
  • private void readObject(ObjectInputStream in) throw IOException, ClassNotFoundException;

在此方法中,如果需要,您可以将其序列化为其他形式,例如您说明的位置的ArrayList,JSON或其他数据格式/方法,并将其重建回readObject()

在您的示例中,您可以添加以下代码:



private void writeObject(ObjectOutputStream oos)
throws IOException {
    // default serialization 
    oos.defaultWriteObject();
    // write the object
    List loc = new ArrayList();
    loc.add(location.x);
    loc.add(location.y);
    loc.add(location.z);
    loc.add(location.uid);
    oos.writeObject(loc);
}

private void readObject(ObjectInputStream ois)
throws ClassNotFoundException, IOException {
    // default deserialization
    ois.defaultReadObject();
    List loc = (List)ois.readObject(); // Replace with real deserialization
    location = new Location(loc.get(0), loc.get(1), loc.get(2), loc.get(3));
    // ... more code

}


答案 2

类似于@momo的答案,但不使用List和自动装箱的int值,这将使它更加紧凑。

private void writeObject(ObjectOutputStream oos) throws IOException {
    // default serialization 
    oos.defaultWriteObject();
    // write the object
    oos.writeInt(location.x);
    oos.writeInt(location.y);
    oos.writeInt(location.z);
    oos.writeInt(location.uid);
}

private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
    // default deserialization
    ois.defaultReadObject();
    location = new Location(ois.readInt(), ois.readInt(), ois.readInt(), ois.readInt());
    // ... more code

}