序列化对象后单例模式被破坏解决方案

package org.ddd.section7.example7_6;

import java.io.Serializable;

public class Earth implements Serializable{
    private static final long serialVersionUID = 1L;
    private volatile static Earth instance;

    public static Earth getInstance() {
          if (instance == null) {
                synchronized (Earth.class) {
                    if (instance == null) {
                        instance = new Earth();
                    }
                }
            }
        return instance;
    }


}
package org.ddd.section7.example7_6;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

public class SerializeTool {
    /**
     * 将对象序列化,并存在在本地文件中
     * @param obj 被序列化的对象
     * @param fileName 存储的本地文件名
     */
    public static void serialize(Object obj, String fileName) throws Exception{
        File file = new File(fileName); //新建一个本地文件,用于存储,序列化的对象字节流
        FileOutputStream output = new FileOutputStream(file); //文件输出流
        ObjectOutputStream oos = new ObjectOutputStream(output); //对象输出流
        oos.writeObject(obj); //将对象写入对象输出流中
        oos.flush(); //提交对象输入流
        oos.close();
        output.close();
    }

    /**
     * 从本地文件中,通过反序列化获取对象
     * @param fileName 本地存储序列化对象的文件
     * @return 反序列化后的对象
     */
    public static Object deSerialize(String fileName) throws Exception{
        File file = new File(fileName); //获取存储对象字节流的本地文件
        FileInputStream input = new FileInputStream(file); //定义文件输入流
        ObjectInputStream ois = new ObjectInputStream(input); //定义对象输入流
        Object obj = ois.readObject(); //从对象输入流中读取对象
        ois.close();
        input.close();
        return obj;
    }

    /**
     * 打印指定文件的文件信息,包括文件名,文件大小等
     * @param fileName 本地文件名
     */
    public static void printFileInfo(String fileName){
        File file = new File(fileName); //获取本地文件

        System.out.println("-----------------------------");
        System.out.println("<FileName>: " + fileName); //打印文件名
        System.out.println("<FileSize>: " + file.length() + " bytes"); //打印文件大小
        System.out.println("-----------------------------");
    }
}
package org.ddd.section7.example7_6;


public class SerializeTest {
    public static void main(String[] args) throws Exception{
        Earth p = new Earth();
        SerializeTool.serialize(p, "temp");
        Earth pp = (Earth) SerializeTool.deSerialize("temp");
        System.out.println(p==pp);
        System.out.println(p);
        System.out.println(pp);
    }
}

输出结果

false
org.ddd.section7.example7_6.Earth@33909752
org.ddd.section7.example7_6.Earth@3d4eac69

简要原因

序列化过程中运用了反射的newInstance创建了对象返回

解决方法

package org.ddd.section7.example7_6;

import java.io.Serializable;

public class Earth implements Serializable{
    private static final long serialVersionUID = 1L;
    private volatile static Earth instance;
    private Earth() {
        // TODO Auto-generated constructor stub
    }
    public static Earth getInstance() {
          if (instance == null) {
                synchronized (Earth.class) {
                    if (instance == null) {
                        instance = new Earth();
                    }
                }
            }
        return instance;
    }
    private Object readResolve() {
        System.out.println("被调用了");
        return getInstance();
    }

    private Object writeReplace() {
        return getInstance();
    }

}

输出

false
org.ddd.section7.example7_6.Earth@3d4eac69
org.ddd.section7.example7_6.Earth@776ec8df
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值