我有一个非常简单的类层次结构:
public class DropdownOption<T> /* does NOT implement Serializable */ {
private T value;
private String label;
public DropdownOption() {
this (null, null);
}
public DropdownOption(T value, String label) {
this.value = value;
this.label = label;
}
public T getValue() {
return value;
}
public void setValue(T value) {
this.value = value;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
}
/**
* Convenience decorator
*/
public class LongIdDropdownOption extends DropdownOption<Long>
implements Serializable {
private static final long serialVersionUID = -3920989081132516015L;
public LongIdDropdownOption() {
super();
}
public LongIdDropdownOption(Long value, String label) {
super(value, label);
}
public Long getId() {
return getValue();
}
public void setId(Long id) {
super.setValue(id);
}
}
当我创建LongIdDropdownOption的新实例时, 实现Serializable;序列化;然后立即反序列化它 - 然后反序列化的对象将其两个字段都设置为null:
public void testSerialization() throws Exception {
LongIdDropdownOption option = new LongIdDropdownOption(1L, "One");
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
ObjectOutputStream os = new ObjectOutputStream(buffer);
os.writeObject(option);
os.close();
ObjectInputStream is = new ObjectInputStream(
new ByteArrayInputStream(buffer.toByteArray()));
LongIdDropdownOption result = (LongIdDropdownOption) is.readObject();
is.close();
assertNotNull(result);
assertEquals("One", result.getLabel()); /** Fails, label is null */
}
当我使基类实现Serializable时,代码开始正常工作。我的问题是......为什么?
答案 0 :(得分:4)
因为只有子类实现Serializable
,所以只有它的字段将由JVM序列化。 JVM不会将父成员视为子类的成员,因为它使用反射来列出类的字段。
答案 1 :(得分:4)
来自Java Docs Here
如果A类没有实现Serializable但是子类B实现了Serializable,那么当B被序列化时,A类的字段会被序列化吗?
仅写出并恢复Serializable对象的字段。仅当对象具有将初始化非可序列化超类型字段的无参数构造函数时,才可以恢复该对象。如果子类可以访问超类的状态,它可以实现writeObject和readObject来保存和恢复该状态。
答案 2 :(得分:4)
如此处所述 - http://java.sun.com/developer/technicalArticles/ALT/serialization“覆盖readObject和writeObject的一个常见原因是序列化非Serializable本身的超类的数据”。
您认为在子类化实例中具有的状态对于序列化而言并非真正可见,因为它不通过您的API或反射。就序列化过程而言,状态属于不实现Serializable的超类。这就是你失去它的地方。
这是一个Java对象序列化规范的链接,应该解释它: http://download.oracle.com/javase/6/docs/platform/serialization/spec/serialTOC.html