Singleton mode: "A class has and has only one instance, and self-instantiation is provided to the system as a whole." ”
There are a number of ways to implement a singleton pattern, such as lazy mode (and so on when the time is instantiated), a Hungry man mode (class loading is instantiated), and so on, here with the A Hungry Man mode method implementation, that is, class loading on the instantiation, a single case pattern application scenario has many, such as an application has a window interface, servlet only one instance , the application is very extensive
package com.test; public class Singleton { private Singleton () {} private static final Singleton INSTANCE = new Singleton (); A hungry man mode public static Singleton getinstance () { return INSTANCE; }}
Singleton mode is basically known to every Java programmer, effective Java first chapter is about object creation and destruction, see the Singleton mode in the serialization will be invalid, this is what I did not know before, so consult the data, and personally verify, the process is very simple, the above single class implementationSerializable接口
Packagecom.test;Importjava.io.Serializable; Public classSingletonImplementsserializable{/*** @Fields Serialversionuid:todo*/ Private Static Final LongSerialversionuid = -6367362518368424353l; PrivateSingleton () {}Private Static FinalSingleton INSTANCE =NewSingleton (); Public StaticSingleton getinstance () {returnINSTANCE; }}
It's time to prove it.
Packagecom.test;ImportJava.io.FileInputStream;Importjava.io.FileNotFoundException;ImportJava.io.FileOutputStream;Importjava.io.IOException;ImportJava.io.ObjectInputStream;ImportJava.io.ObjectOutputStream; Public classTest { Public Static voidMain (string[] args)throwsFileNotFoundException, IOException, classnotfoundexception {Singleton before=singleton.getinstance (); //serialization, writing an object to a fileObjectOutputStream Oos =NewObjectOutputStream (NewFileOutputStream ("D:\\objectfile")); Oos.writeobject (before); Oos.close (); //deserialize, read file, revert to objectObjectInputStream Ois =NewObjectInputStream (NewFileInputStream ("D:\\objectfile")); Singleton After=(Singleton) ois.readobject (); Ois.close (); //Validation ResultsSystem.out.println (before = =After ); }}
Output: false
This means that once the object is serialized, the singleton pattern is broken, because the re-read object is not the previous object, it regenerates one!
So the question is, how to solve the contradiction between single-case pattern and serialization?
Effective gives a workaround by simply adding areadResolve方法,即
Packagecom.test;Importjava.io.Serializable; Public classSingletonImplementsserializable{/*** @Fields Serialversionuid:todo*/ Private Static Final LongSerialversionuid = -6367362518368424353l; PrivateSingleton () {}Private Static FinalSingleton INSTANCE =NewSingleton (); Public StaticSingleton getinstance () {returnINSTANCE; } PrivateObject readresolve () {returnINSTANCE; }}
Running the previous test class again, the result turns out to be true again, stating that the deserialization singleton pattern is not broken! Refer to this blog http://www.hollischuang.com/archives/1144 for the principles of this article
The ultimate solution, enum Class!
It is extremely simple to use and requires only
Package com.test; Import java.io.Serializable; Public enum Implements serializable{ INSTANCE;}
And then test it again.
Packagecom.test;ImportJava.io.FileInputStream;Importjava.io.FileNotFoundException;ImportJava.io.FileOutputStream;Importjava.io.IOException;ImportJava.io.ObjectInputStream;ImportJava.io.ObjectOutputStream; Public classTest { Public Static voidMain (string[] args)throwsFileNotFoundException, IOException, classnotfoundexception {Singleton before=singleton.instance; //Serialization ofObjectOutputStream Oos =NewObjectOutputStream (NewFileOutputStream ("D:\\objectfile")); Oos.writeobject (before); Oos.close (); //deserializationObjectInputStream Ois =NewObjectInputStream (NewFileInputStream ("D:\\objectfile")); Singleton After=(Singleton) ois.readobject (); Ois.close (); //Validation ResultsSystem.out.println (before = =After ); }}
Output is True
Effective single-instance mode and serialization of Java notes