From: http://blog.csdn.net/haydenwang8287/archive/2010/10/25/5964130.aspx
Serialization is a very common and powerful function in Java. In my opinion, it is one of the most common functions of Java to save Java objects to a disk and read them from the disk later. In basic cases, serialization can "simply work )". However, as more and more complex object formats and design patterns are adopted, the possibility of transparent object serialization being "simple to work" becomes increasingly impossible. Processing an instance of a controllable set, such as singleton and enum, is a scenario where serialization requires some extra help.
In any scenario where the single-instance object can be sequenced, it is very important to ensure that the single-instance object is used. This is implemented through the readresolve () interface. Singleton is a good example:
- Public final class mysingleton {
- Private mysingleton (){}
- Private Static final mysingleton instance = new mysingleton ();
- Public static mysingleton getinstance () {return instance ;}
- }
In the above example, there is only one way to get the instance of mysingleton-that is, use the getinstance () method. Then, after simply adding an interface implementation, this code becomes unavailable:
- Public final class mysingleton implements serializable {
- //.
Now, with the serializable tool, we can write a single instance object to a disk and then read it back to effectively obtain an instance. Even if the constructor is private, the serializable tool can still create a new instance of the class in a special way. The serialization operation provides a very special hook-class with a private instantiated method readresolve (), this method ensures that class developers have a say in what object will be returned by serialization. It is strange enough that readresolve () is not static, but is referenced when serialization creates an instance. We started to experience this in one minute. The following example shows how readresolve () plays a role in our singleton:
- Public final class mysingleton {
- Private mysingleton (){}
- Private Static final mysingleton instance = new mysingleton ();
- Public static mysingleton getinstance () {return instance ;}
- Private object readresolve () throws objectstreamexception {
- // Instead of the object we're on,
- // Return the class variable instance
- Return instance;
- }
- }
So far, the situation is quite good. However, when processing multiple instances, the situation becomes a bit complicated. To explain this, I will demonstrate this through a type-safe enmumeration. Remember that the enum type of JDK 5 has automatically handled this readresolve situation. The following is an example of a small enumeration:
- Public final class sides {
- Private int value;
- Private sides (INT newval) {value = newval ;}
- Private Static final int left_value = 1;
- Private Static final int right_value = 2;
- Private Static final int top_value = 3;
- Private Static final int bottom_value = 4;
- Public static final left = new sides (left_value );
- Public static final right = new sides (right_value );
- Public static final Top = new sides (top_value );
- Public static final bottom = new sides (bottom_value );
- }
Now we can implement serialization to determine whether the key of the returned instance depends on the value set by the object itself:
- Public final class sides implements serializable {
- Private int value;
- Private sides (INT newval) {value = newval ;}
- Private Static final int left_value = 1;
- Private Static final int right_value = 2;
- Private Static final int top_value = 3;
- Private Static final int bottom_value = 4;
- Public static final left = new sides (left_value );
- Public static final right = new sides (right_value );
- Public static final Top = new sides (top_value );
- Public static final bottom = new sides (bottom_value );
- Private object readresolve () throws objectstreamexception {
- // Switch on this instance's value to figure out which class variable
- // This is meant to match
- Switch (value ){
- Case left_value: return left;
- Case right_value: return right;
- Case top_value: Return top;
- Case bottom_value: Return bottom;
- }
- Return NULL;
- }
- }