Why readObject method must call defaultReadObject to preserve backward and forward compatibility

廉价感情. 提交于 2019-12-24 11:44:40

问题


I am going through Effective Java, item 75:

If all instance fields are transient, it is technically permissible to dispense with invoking defaultWriteObject and defaultReadObject , but it is not recommended. Even if all instance fields are transient, invoking defaultWriteObject affects the serialized form, resulting in greatly enhanced flexibility. The resulting serialized form makes it possible to add nontransient instance fields in a later release while preserving backward and forward compatibility. If an instance is serialized in a later version and deserialized in an earlier version, the added fields will be ignored. Had the earlier version’s readObject method failed to invoke defaultReadObject , the deserialization would fail with a StreamCorruptedException

The question is why it's necessary to call defaultReadObject/defaultWriteObject to preserve backward and forward compatibility?

Can you explain with an example?

Why the added fields will be ignored?

Why a StreamCorruptedException will be thrown?


回答1:


Because that's what happens by default. If you add these methods you have to at least do what would have happened if they weren't present. Otherwise you won't read/write the stream in a compatible manner. You can't just completely replace what would have been written without risking compatibility.

Unless you can magically change both ends at the same time and there are no permanently serialized streams anywhere, e.g. in files or a database.




回答2:


The answer to your question is actually in the excerpt you just provided (though it is a bit vague, I admit). The crucial part is this:

If an instance is serialized in a later version and deserialized in an earlier version, the added fields will be ignored. Had the earlier version’s readObject method failed to invoke defaultReadObject, the deserialization would fail [...]

Imagine the following example: You have an object with only transient fields in it. You decide to skip defaultWriteObject/defaultReadObject calls, because you assume that you do not need it.

Then you add new features to your program, and you also add some non-transient fields to this object. You call defaultWriteObject properly this time, and you expect that the old version of your application will still function (ignoring the new field of course). But it won't. Instead of ignoring the new field you just added because it found unexpected data there.



来源:https://stackoverflow.com/questions/33363646/why-readobject-method-must-call-defaultreadobject-to-preserve-backward-and-forwa

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!