通过反序列化机制会破坏单例类的规则
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Singleton implements Serializable {
private static Singleton instance;
private String name;
private Singleton(String name) {
this.name = name;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj.getClass() == Singleton.class) {
Singleton target = (Singleton) obj;
return target.name.equals(this.name);
}
return false;
}
public static Singleton getInstance(String name) {
if (instance == null) {
instance = new Singleton(name);
}
return instance;
}
public int hashCode() {
return name.hashCode();
}
}
public class SingletonTest {
public static void main(String[] args) {
Singleton s = Singleton.getInstance("Singleton");
System.out.println("Singleton对象创建完成~");
Singleton s2 = null;
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("b.bin"));
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("b.bin"));
oos.writeObject(s);
oos.flush();
s2 = (Singleton) ois.readObject();
//两个对象的实例化变量完全相等,输出true
System.out.println(s.equals(s2));
//两个对象不相同,输出false
System.out.println(s == s2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
通过反序列化恢复出来的对象具有完成相同的实例变量值,但系统会产生两个对象.
为单例类提供readResolve()方法
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.ObjectStreamException;
import java.io.Serializable;
class Singleton implements Serializable {
private static Singleton instance;
private String name;
private Singleton(String name) {
this.name = name;
}
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj.getClass() == Singleton.class) {
Singleton target = (Singleton) obj;
return target.name.equals(this.name);
}
return false;
}
public static Singleton getInstance(String name) {
if (instance == null) {
instance = new Singleton(name);
}
return instance;
}
public int hashCode() {
return name.hashCode();
}
private Object readResolve() throws ObjectStreamException {
return instance;
}
}
public class SingletonTest {
public static void main(String[] args) {
Singleton s = Singleton.getInstance("Singleton");
System.out.println("Singleton对象创建完成~");
Singleton s2 = null;
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("b.bin"));
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("b.bin"));
oos.writeObject(s);
oos.flush();
s2 = (Singleton) ois.readObject();
//两个对象的实例化变量完全相等,输出true
System.out.println(s.equals(s2));
//两个对象不相同,输出true
System.out.println(s == s2);
} catch (Exception e) {
e.printStackTrace();
}
}
}
s==s2为true,表明反序列化机制恢复出来的java对象依然是单例类。当JVM反序列化一个新对象时,系统会自动调用readResolve()方法放回指定好的对象,从而保证系统通过反序列化机制不会产生多个java对象。