Java自定义序列化

Ale*_*ing 61 java serialization

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

// 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
Run Code Online (Sandbox Code Playgroud)

我怎样才能做到这一点?

mom*_*omo 63

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

报价:

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

  • private void writeObject(ObjectOutputStream out)抛出IOException;
  • private void readObject(ObjectInputStream in)抛出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

}

Run Code Online (Sandbox Code Playgroud)

  • 你没有*在一个`ArrayList`或JSON对象或其他东西中解决所有问题.你可以做`oos.writeInt(x); oos.writeInt(Y); ...`和相应的输入方法顺序相同. (5认同)

Pet*_*rey 33

类似于@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

}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这是一个好点.但是,在我的实际代码中,我使用的不仅仅是数组,所以我使用`writeObject`代替.我接受了momo的答案,因为它是第一个,但对于给出的情况,这可能是一个更好的答案. (4认同)
  • 这个答案好多了 (2认同)