通过反序列化获取多个实例会破坏单例类的规则

通过反序列化机制会破坏单例类的规则


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对象。

posted @ 2017-05-29 16:37  %hahahaha%  阅读(951)  评论(1编辑  收藏  举报