6.2其他方法实现单例模式
MyObject.java
public class MyObject {
private static class MyObjectHandler{
private static MyObject myObject = new MyObject();
}
private MyObject(){}
public static MyObject getInstance(){
return MyObjectHandler.myObject;
}
}
静态实现的单例对象,在序列化和反序列化时会出现违背单例的情况。
解决方法是,在单例类定义中添加 readResolve 代码段:
//静态属性
protected Object readResolve(){
System.out.println("调用了 readResolve");
return MyObject.myObject;
}
或
//静态内部类
protected Object readResolve(){
System.out.println("调用了 readResolve");
return MyObjectHandler.myObject;
}
MyObject.java
import java.io.Serializable;
public class MyObject implements Serializable {
private static class MyObjectHandler{
private static MyObject myObject = new MyObject();
}
private MyObject(){}
public static MyObject getInstance(){
return MyObjectHandler.myObject;
}
}
Run.java
public class Run {
public static void main(String[] args) {
try {
MyObject myObject = MyObject.getInstance();
FileOutputStream fos = new FileOutputStream(new File("a.txt"));
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(myObject);
System.out.println(myObject.hashCode());
oos.close();
fos.close();
}catch (IOException e){
}
try{
FileInputStream fis = new FileInputStream(new File("a.txt"));
ObjectInputStream ois = new ObjectInputStream(fis);
MyObject myObject = (MyObject) ois.readObject();
System.out.println(myObject.hashCode());
ois.close();
fis.close();
}catch (IOException e ){
}catch (ClassNotFoundException e){
}
}
}
运行结果
1267032364
1598924227
使用的是静态内部类实现单例模式,但序列化写对象和反序列化读对象得到的却不是同一个,违背单例模式。
解决方法:修改 MyObject.java
import java.io.Serializable;
public class MyObject implements Serializable {
private static class MyObjectHandler{
private static MyObject myObject = new MyObject();
}
private MyObject(){}
public static MyObject getInstance(){
return MyObjectHandler.myObject;
}
protected Object readResolve(){
System.out.println("调用了 readResolve");
return MyObjectHandler.myObject;
}
}
修改之后运行结果显示,序列化对象和反序列化得到的对象是同一个对象。
1267032364
调用了 readResolve
1267032364
实质上,静态块的实现原理与静态属性相同,即
private static MyObject myObject = null;
static {
myObject = new MyObject();
}
相当于
private static MyObject myObject = new MyObject();
静态块实现单例
import java.io.Serializable;
public class MyObject implements Serializable {
private static MyObject myObject = null;
static {
myObject = new MyObject();
}
private MyObject(){}
public static MyObject getInstance(){
return MyObject.myObject;
}
//用于解决反序列化问题
protected Object readResolve(){
System.out.println("调用了 readResolve");
return MyObject.myObject;
}
}
这种方式实现单例,序列化的对象和反序列化得到的对象是同一个对象。
MyObject.java
import java.io.Serializable;
public class MyObject implements Serializable {
public enum MyEnumSingleton {
stringFactory;
private String string = new String("Fine");
public String get(){
return string;
}
};
public static String get(){
return MyEnumSingleton.stringFactory.get();
}
}
MyThread.java
public class MyThread extends Thread{
@Override
public void run(){
for (int i = 0; i < 5; i++) {
System.out.println(MyObject.get().hashCode());
}
}
}
Run.java
public class Run {
public static void main(String[] args) {
MyThread A = new MyThread();
MyThread B = new MyThread();
MyThread C = new MyThread();
A.start();
B.start();
C.start();
}
}