Java 如何不序列化继承的非瞬态字段? 问题
我有一个可序列化的类(我们称之为a)和一个非瞬态布尔字段,以及一个子类(B),对于该子类,同一个字段应该是瞬态的。我该怎么做 更准确地说,我希望在反序列化B时将该字段还原为默认布尔值(Java 如何不序列化继承的非瞬态字段? 问题,java,serialization,Java,Serialization,我有一个可序列化的类(我们称之为a)和一个非瞬态布尔字段,以及一个子类(B),对于该子类,同一个字段应该是瞬态的。我该怎么做 更准确地说,我希望在反序列化B时将该字段还原为默认布尔值(false),尽管我希望在反序列化A时将其还原为正确的值。但从A继承的其他字段仍应还原 从功能上讲,A表示在会话之间恢复的对象,B是一种特定类型的A,其状态应在每个新会话上重置 快速代码示例: 公共类A实现java.io.Serializable{ 私有字符串标签; //非瞬态 私有布尔域; 公共字符串getLab
false
),尽管我希望在反序列化A时将其还原为正确的值。但从A继承的其他字段仍应还原
从功能上讲,A表示在会话之间恢复的对象,B是一种特定类型的A,其状态应在每个新会话上重置
快速代码示例:
公共类A实现java.io.Serializable{
私有字符串标签;
//非瞬态
私有布尔域;
公共字符串getLabel(){
退货标签;
}
公共void setLabel(字符串标签){
this.label=标签;
}
公共布尔值字段(){
返回字段;
}
公共无效设置字段(布尔字段){
this.field=字段;
}
}
公共类B扩展了A{
//此类的字段应该是暂时的
//标签应保持非暂时性
}
我选择不保留的一些可能的解决方案
- 一个简单的解决方案是将
更改为B extends A
,使字段暂时化,并将A extends B
添加到A以序列化字段。然而,writeObject()
的功能含义,我不认为将其还原是明智的B扩展了A
- 我可以实现一个
方法,该方法将覆盖字段的反序列化值。然而,这感觉像是一个肮脏的解决方案,我不希望使用它,除非没有其他选择readObject()
- 我试图编写一个
方法来模拟一个瞬态字段,但它不起作用,我也说不出原因。如果有人有线索,那可能是我的解决方案:writeObject()
公共类B扩展了{
私有void writeObject(ObjectOutputStream out)引发IOException{
//保存当前状态
布尔字段=isField();
//已同步以确保未询问此实例
//而更改为序列化
已同步(此){
//模拟瞬态并序列化
设置字段(假);
out.defaultWriteObject();
//恢复状态
设置字段(字段);
}
}
}
- 编辑:@rocketboy使用阴影的解决方案很有效,但我不喜欢阴影,因为它会留下一个未使用的字段(A的非瞬态字段永远不会被使用,而B的瞬态版本将被写入和读取)。不过,这可能是一个解决方案。经过实验的Java开发人员是否认为这是一个干净的解决方案
公共类B扩展了{
//阴影A的场
私有瞬态布尔域;
@凌驾
公共布尔getField(){
返回字段;
}
@凌驾
公共无效设置字段(布尔字段){
this.field=字段;
}
}
答案 按照@m1o2的建议,我已经能够使用接口实现我的解决方案:
public类B扩展了实现java.io.Externalizable的{
//不要忘记有一个公共的无参数构造函数
//让序列化工作
公共图书馆B(){
}
@凌驾
public void writeExternal(ObjectOutput out)引发IOException{
//只写我感兴趣的领域
writeObject(getLabel());
}
@凌驾
public void readExternal(ObjectInput in)引发IOException,
ClassNotFoundException{
//按写入顺序读取序列化字段
setLabel(.readObject()中的字符串);
}
}
但是请注意,这是适用的,因为A和B是简单的类。对于具有许多字段且有发展趋势的类,这可能会花费更多(除非使用一些基于反射的代码)。如果您不关心超类字段(所有字段)你可以使用界面我想你当然可以在孩子的课堂上掩盖它。这不是违反了Liskov的替代原则吗?@rocketboy:是的,我可以很容易地做到。例如,如果我的领域受到保护。但我通常使用私有字段,子类必须像其他任何人一样使用he访问器@太空卡车司机:我不知道利斯科夫的替代原理。你问了一个很好的问题。快速阅读让我觉得Java的继承编码规则确保了这一原则得到尊重。我觉得还可以。我不更改对象的属性,我只希望在每次会话开始时重新设置它们(以这种方式编写后,
readObject()
解决方案感觉不那么糟糕…。@rocketboy我使用阴影添加了一个解决方案。我关心超类中的一些字段,但在这种情况下,Externalizable符合我的需要。我在问题的末尾加了一个例子。谢谢