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


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

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

  • 相关阅读:
    问题 A: C#抽象类Vehicles
    最短路练习
    BFS
    poj 1083 Moving Tables
    组合数
    hdu 1443 Joseph【约瑟夫环】
    poj 2449 Remmarguts' Date【第K短路】
    hdu 1695 GCD 【莫比乌斯函数】
    hdu 2178 猜数字
    bzoj 2440 完全平方数 【莫比乌斯函数】
  • 原文地址:https://www.cnblogs.com/Onlywjy/p/6918317.html
Copyright © 2020-2023  润新知