一尘不染

具有不可序列化部分的Java序列化

java

我有:

class MyClass extends MyClass2 implements Serializable {
  //...
}

在MyClass2中是无法序列化的属性。如何序列化(和反序列化)此对象?

更正:MyClass2当然不是接口,而是类。


阅读 219

收藏
2020-09-08

共1个答案

一尘不染

正如其他人指出的那样,Josh Bloch的Effective
Java的
第11章是有关Java序列化的必不可少的资源。

该章中与您的问题有关的几点:

  • 假设您要序列化MyClass2中不可序列化字段的状态,则MyClass必须可以直接访问该字段,也可以通过getter和setter对其进行访问。MyClass必须通过提供readObject和writeObject方法来实现自定义序列化。
  • 不可序列化字段的类必须具有一个API,以允许获取其状态(用于写入对象流),然后实例化具有该状态的新实例(稍后从对象流中读取时)。
  • 根据有效Java的第74项,MyClass2 必须 具有MyClass可访问的no-arg构造函数,否则MyClass不可能扩展MyClass2并实现Serializable。

我在下面写了一个简单的例子来说明这一点。

class MyClass extends MyClass2 implements Serializable{

  public MyClass(int quantity) {
    setNonSerializableProperty(new NonSerializableClass(quantity));
  }

  private void writeObject(java.io.ObjectOutputStream out)
  throws IOException{
    // note, here we don't need out.defaultWriteObject(); because
    // MyClass has no other state to serialize
    out.writeInt(super.getNonSerializableProperty().getQuantity());
  }

  private void readObject(java.io.ObjectInputStream in)
  throws IOException {
    // note, here we don't need in.defaultReadObject();
    // because MyClass has no other state to deserialize
    super.setNonSerializableProperty(new NonSerializableClass(in.readInt()));
  }
}

/* this class must have no-arg constructor accessible to MyClass */
class MyClass2 {

  /* this property must be gettable/settable by MyClass.  It cannot be final, therefore. */
  private NonSerializableClass nonSerializableProperty;

  public void setNonSerializableProperty(NonSerializableClass nonSerializableProperty) {
    this.nonSerializableProperty = nonSerializableProperty;
  }

  public NonSerializableClass getNonSerializableProperty() {
    return nonSerializableProperty;
  }
}

class NonSerializableClass{

  private final int quantity;

  public NonSerializableClass(int quantity){
    this.quantity = quantity;
  }

  public int getQuantity() {
    return quantity;
  }
}
2020-09-08