Reputation: 13046
I periodically see Java classes with the following structure:
class MyClass implements Serializable {
private static final long serialVersionUID = 1L;
// ...
private void writeObject(final java.io.ObjectOutputStream s) throws IOException {
s.defaultWriteObject();
}
private void readObject(final java.io.ObjectInputStream s) throws IOException, ClassNotFoundException {
s.defaultReadObject();
}
}
As I understand for default serialization you only need to declare implementation of serializable
interface and define serialVersionUID
. Is there any reason to declare write / read methods with just default implementation? I am tired from analyzer warnings about code duplication.
Don't see any really clear guide for this topic. Everything either is somewhat outdated or pretty subjective.
Upvotes: 4
Views: 219
Reputation: 96385
The ObjectInputStream#defaultReadObject and ObjectOutputStream#defaultWriteObject methods are provided for cases where you want to write the fields using the defaults plus you have other information to read or write, or if you want to modify what gets read or written. If you don't want to add or change anything, there's no advantage to adding explicit calls over just implementing Serializable.
The Java Object Serialization Specification seems like a good reference for this, section 1.7 (Accessing Serializable Fields of a Class) says:
The default mechanism is used automatically when reading or writing objects that implement the Serializable interface and do no further customization. The serializable fields are mapped to the corresponding fields of the class and values are either written to the stream from those fields or are read in and assigned respectively. If the class provides writeObject and readObject methods, the default mechanism can be invoked by calling defaultWriteObject and defaultReadObject. When the writeObject and readObject methods are implemented, the class has an opportunity to modify the serializable field values before they are written or after they are read.
Upvotes: 4
Reputation: 3996
You only need to implement writeObject
and readObject
when you do custom serialization. For serialVersionUID please read the following:
If a serializable class does not explicitly declare a serialVersionUID, then the serialization runtime will calculate a default serialVersionUID value for that class based on various aspects of the class, as described in the Java(TM) Object Serialization Specification. However, it is strongly recommended that all serializable classes explicitly declare serialVersionUID values, since the default serialVersionUID computation is highly sensitive to class details that may vary depending on compiler implementations, and can thus result in unexpected InvalidClassExceptions during deserialization. Therefore, to guarantee a consistent serialVersionUID value across different java compiler implementations, a serializable class must declare an explicit serialVersionUID value. It is also strongly advised that explicit serialVersionUID declarations use the private modifier where possible, since such declarations apply only to the immediately declaring class--serialVersionUID fields are not useful as inherited members. Array classes cannot declare an explicit serialVersionUID, so they always have the default computed value, but the requirement for matching serialVersionUID values is waived for array classes.
http://docs.oracle.com/javase/8/docs/api/java/io/Serializable.html
Upvotes: 1