16

When I read the about the Serializable interface in Thinking in java, there is a sentence that says:

If you use the default mechanism to write the non-transient parts of your object, you must call defaultWriteObject( ) as the first operation in writeObject( ), and defaultReadObject( ) as the first operation in readObject( ).

And in docs.oracle.com 5.6.2:

Adding writeObject/readObject methods - If the version reading the stream has these methods then readObject is expected, as usual, to read the required data written to the stream by the default serialization. It should call defaultReadObject first before reading any optional data. The writeObject method is expected as usual to call defaultWriteObject to write the required data and then may write optional data.

So If I don't call defaultWriteObject first, and if I write something else before that call, will there be any problem? I have tried it, but it seems that it still works well in my example. So If there is to be any problem, under what condition could it occur ?

Regexident
  • 29,441
  • 10
  • 93
  • 100
HonestManXin
  • 307
  • 3
  • 7
  • It is so because it is so. Unless you get one of the original designers here, which isn't likely, anything you get here will be more or less uninformed guesswork. Not constructive. – user207421 Apr 27 '13 at 10:49

4 Answers4

6

Java Object Serialization Specification is vague on this subject:

Either ObjectOutputStream's defaultWriteObject or writeFields method must be called once (and only once) before writing any optional data that will be needed by the corresponding readObject method to restore the state of the object; even if no optional data is written, defaultWriteObject or writeFields must still be invoked once. If defaultWriteObject or writeFields is not invoked once prior to the writing of optional data (if any), then the behavior of instance deserialization is undefined in cases where the ObjectInputStream cannot resolve the class which defined the writeObject method in question.

Here's an old thread which gives an example case when problems might occur.

And here's a JBoss AS Jira ticket with another example.

Andrew Logvinov
  • 21,181
  • 6
  • 52
  • 54
  • 1
    I recently encountered this, and it caused tricky-to-debug StreamCorruptedException in the receiver, so I strongly recommend always calling defaultRead/WriteObject even if all the members of your class are transient. – Brett Kail Apr 26 '13 at 16:24
  • does it mean its more of a call to constructor to build object ?before serialize and deserialize ? – amarnath harish Aug 22 '18 at 05:30
3

It's described in Effective Java:

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 .

Dmytro Kryvenko
  • 343
  • 4
  • 16
2

I think the key word in the documentation is "should", which means that you don't have to.

I think it's more of a best practice than anything else. If I read your code the first time and see that you defaulted the read/write on the first line, I can just say to myself "ok, done with 90% of the class", and concentrate on your custom code which takes care of all non-transient, non-static instance variables..

The most important thing is to read/write in the same order. Apart from that you are free to do as you like.

Jalayn
  • 8,934
  • 5
  • 34
  • 51
0

I think that's because you know what you do on both sides and do the "same" or better the according opposite ...

BUT: If some other programmer would write a deserialization against your serialization without knowing that you do not use the default, he probably will use the recommended defaultReadObject and then run into weird exceptions.

Fildor
  • 14,510
  • 4
  • 35
  • 67