Excellent question! First, let's get a definition for encapsulation and go from there. This wikipedia article defines encapsulation in the following way:
- A language mechanism for restricting access to some of the object's components.
- A language construct that facilitates the bundling of data with the methods (or other functions) operating on that data.
Serialization, at least the way Java does it, has ramifications for both of these notions. When you implement the Serializable
interface in Java, you are essentially telling the JVM that all of your non-transient
member variables and the order in which they are declared defines the contract by which objects can be reconstructed from a byte stream. This works recursively if and only if all of your member variable's class definitions also implement Serializable
, and this is where you can get into trouble.
The Encapsulation Problem
Based on the previous definition of encapsulation, particularly the first item, encapsulation prevents you from knowing anything about how the object you are dealing with actually works under the hood, with respect to its member variables. Implementing Serializable
"correctly" forces you as a developer to know more about the objects you are dealing with than you probably care about in the functional sense. In this sense, implementing Serializable
directly opposes encapsulation.
Custom Serialization
In every case, serialization requires knowledge about what data constitutes an "object" of a particular type. Java's Serializable
interface takes this to the extreme by forcing you to know the transient
state of every member variable of every Object
you hope to serialize. You could get around this by defining a serialization mechanism external to the types that need to be serialized, but there will be design tradeoffs - e.g. you'd probably need to deal with Objects at the level of the interface(s) they implement instead of direct interaction with their member variables, and you may lose some of the ability to reconstruct the exact Object type from a serialized byte stream.