1. 程式人生 > >用java原生介面Serializable實現對單例物件的序列化

用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();
        }

    }
}

最後呈現的結果
這裡寫圖片描述