1. 程式人生 > 其它 >Java Serializable(序列化)

Java Serializable(序列化)

技術標籤:# java程式java

序列化的意義

序列化機制將Java物件轉換為位元組序列,這些位元組序列可以儲存在磁碟上,或通過網路傳輸。序列化機制使得java物件可以脫離程式而獨立存在。

Java講究萬物皆物件,資訊大多數都儲存在物件內部(屬性),所以需要儲存物件至關重要。然而儲存物件的前提是物件已經進行了序列化。

使用場景

  • 把物件進行網路傳輸
  • 把物件儲存到磁碟
  • 資料快取

可序列化的類

  • 如果父類是可序列化的,那麼子類可以序列化
  • 如果類的全部成員是可序列化的,那麼類可以序列化

序列化和反序列化的Demo

Person類

//Student繼承Serializable,可以進行序列化
public
class Student implements Serializable { //無參建構函式 public Student() { } //有參建構函式 public Student(String name) { this.name = name; } /* name是Student的成員變數,name的型別是String(可序列化),所以Student可以正常序列化。 */ private String name; //get public String getName() { return
name; } //set public void setName(String name) { this.name = name; } //重寫equlas @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Student student = (Student) o;
return name.equals(student.name); } //重寫hashcode @Override public int hashCode() { return Objects.hash(name); } //重寫tostring @Override public String toString() { return "student{" + "name='" + name + '\'' + '}'; } }

主函式

	/*
    1、引數
    file是檔案物件
    object是寫入的物件
    2、主要功能
    把物件序列化後寫入檔案,規則:一個檔案只寫一個物件
     */
    public static void writer(File file, Object object) {
        //檔案不存在就建立檔案
        if (!file.exists()) {
            try {
                //建立檔案
                file.createNewFile();
                System.out.println("檔案不存在,建立檔案成功...");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        System.out.println("開始寫檔案...");
        try {

            //例項化FileOutputStream物件
            FileOutputStream fileOutputStream = new FileOutputStream(file);

            //例項化objectOutputStream物件
            ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);

            //把物件寫入檔案
            objectOutputStream.writeObject(object);

            //關閉流
            objectOutputStream.close();
            fileOutputStream.close();
            System.out.println("寫入結束,關閉流成功...");
        } catch (IOException e) {
            System.out.println("寫入失敗!");
            e.printStackTrace();
        }
    }

    /*
    1、引數
    file是檔案物件
    2、主要功能
    把序列化後的檔案轉換為物件
    3、返回值
    一個Object類的物件
     */
    public static Object reader(File file) {
        //如果檔案不存在退出程式
        if (!file.exists()) {
            System.out.println("讀取的檔案不存在!");
            //退出程式
            System.exit(1);
        }
        System.out.println("開始讀檔案...");
        try {
            //例項化FileInputStream物件
            FileInputStream fileInputStream = new FileInputStream(file);

            //例項化ObjectInputStream物件
            ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
            //讀取物件
            Object object = null;
            try {
                object = objectInputStream.readObject();
            } catch (ClassNotFoundException e) {
                System.out.println("讀取失敗!");
                e.printStackTrace();
            }
            //關閉連線
            objectInputStream.close();
            fileInputStream.close();
            System.out.println("讀取結束,關閉流成功...");
            //返回讀取的物件
            return object;
        } catch (IOException e) {
            System.out.println("讀取失敗!");
            e.printStackTrace();
        }
        //發生異常返回null
        return null;
    }

    public static void main(String[] args) {

        //例項化多個物件
        Student a = new Student("小紅");
        Student b = new Student("小藍");
        Student c = new Student("小黃");
        //定義集合
        List<Student> list = new ArrayList<>();
        //把物件加入集合
        list.add(a);
        list.add(b);
        list.add(c);

        //檔案路徑
        String filePath = "object.txt";

        //例項化File物件
        File file = new File(filePath);

        //把集合物件序列化後寫入檔案
        writer(file, list);

        //把檔案進行反序列化轉為物件
        Object reader = reader(file);

        //把物件進行強制轉換,因為返回的是Object類
        List<Student> students = (List<Student>) reader;

        //遍歷輸出物件
        for (Student student : students) {
            System.out.println(student);
        }
    }

總結

  • 反序列化不會呼叫構造方法(感覺這個結論有點傻)
  • 一個物件不會被多次序列化
    比如:你把物件A序列化後寫入檔案,然後又一次把物件A序列化寫入檔案,這時,系統發現A已經存在於檔案中,只會寫入A的編號(指標的感覺)。
    帶來的bug:如果A先寫入檔案,然後A屬性值發生了改變,這時想更新檔案中的A,再把A寫入檔案,系統儲存的是修改前的屬性值(A第一次存入檔案的屬性)。