用java原生接口Serializable实现对单例对象的序列化

单例类,也是将要序列化的类

package test;

import java.io.Serializable;
import java.util.Date;

/**
 * 定义一个可序列化的单例类,单例实现方法是静态内部类实现 同时为了在序列化后,再次反序列化获得对象还是单例模式。用readResolve方法
 * 对于这个不是很懂。
 * 
 * @author cindy
 *
 */
public class MyObject implements Serializable {

    /**
     * 序列码
     */
    private static final long serialVersionUID = 8881L;

    private String name = "";
    private Date birthday = null;
    private String address = "";

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public static long getSerialversionuid() {
        return serialVersionUID;
    }

    private MyObject() {

        // TODO Auto-generated constructor stub
    }

    // 内部类实现单例模式
    private static class MyObjectHandler {
        private static final MyObject myobject = new MyObject();
    }

    public static MyObject getInstance() {
        return MyObjectHandler.myobject;

    }

    protected Object readResolve() {
        System.out.println("调用了readResolve方法");
        return MyObjectHandler.myobject;
    }

}

文件服务类

序列化是将数据持久化存到文件中的

package file.service;

import java.io.File;
import java.io.IOException;

import test.run.SerialAndUnserial;

public class FileService {

    public FileService() {
        // TODO Auto-generated constructor stub
    }

    public static File createAndOpenFile(String filepath) {
        if (filepath == null || filepath == "") {
            return null;

        }
        String basePath = SerialAndUnserial.class.getResource("/").getFile();
        // 这里你可以看到classpath的地址在哪里
        System.out.println("classpath路径" + basePath);
        File file = null;

        /**
         * 有getCanonicalFile的效果是将含有的跳转到上层目录的../去掉。构成一个可以解析的目录
         * 形成这种形式/home/cindy/eclipseworkspace/singleton_serial/txt/object. txt
         * 在没有getCanonicalFile()方法调用前是这样的。
         * /home/cindy/eclipseworkspace/singleton_serial/../txt/object.txt
         * 你可以把那个方法去掉试下。貌似去掉也可以正常执行。
         */
        try {
            file = new File(basePath, filepath).getCanonicalFile();
        } catch (IOException e2) {
            // TODO Auto-generated catch block
            e2.printStackTrace();
        }

        System.out.println("该路径的父级目录" + file.getParent());

        // 判定这个抽象路径名表示的路径是否存在
        System.out.println(file.exists());
        if (!file.exists()) {
            // 将所有缺少父级目录都创建好
            file.getParentFile().mkdirs();
            try {// 最后创建文件
                file.createNewFile();
                return file;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        System.out.println(file.exists());
        return file;
    }

}

测试用例

package test.run;

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

import file.service.FileService;
import test.MyObject;

public class SerialAndUnserial {

    public SerialAndUnserial() {
        // TODO Auto-generated constructor stub
    }

    @SuppressWarnings("deprecation")
    public static void main(String[] args) {
        MyObject myObject = MyObject.getInstance();

        myObject.setAddress("广州市番禺区广东工业大学");
        myObject.setBirthday(new Date(2012, 0, 21));
        myObject.setName("vincent");
        String relativePath = "../txt/object.txt";
        // System.out.println(SerialAndUnserial.class.getResource("/").getFile());
        // System.out.println(SerialAndUnserial.class.getClassLoader().getResource("/").getFile());
        File file = FileService.createAndOpenFile(relativePath);
        System.out.println(file.getPath());
        try {
            FileOutputStream fos = new FileOutputStream(file);
            ObjectOutputStream oos = new ObjectOutputStream(fos);
            oos.writeObject(myObject);
            oos.close();
            fos.close();
            System.out.println("MyObject实例序列化前的哈希值" + myObject.hashCode());
            System.out.println(myObject.getAddress() + "\t" + myObject.getName() + "\t" + myObject.getBirthday());

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {

        }
        try {
            FileInputStream fis = new FileInputStream(file);
            ObjectInputStream objectInputStream = new ObjectInputStream(fis);
            MyObject mObject = (MyObject) objectInputStream.readObject();
            objectInputStream.close();
            fis.close();
            System.out.println("MyObject实例序列化后的哈希值" + mObject.hashCode());
            System.out.println(mObject.getAddress() + "\t" + mObject.getName() + "\t" + mObject.getBirthday());

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
}

最后呈现的结果
用java原生接口Serializable实现对单例对象的序列化_第1张图片

你可能感兴趣的:(java-8学习记录)