1. 程式人生 > >java 序列化簡介

java 序列化簡介

序列化: 把java物件轉換為位元組序列的過程
反序列化:把位元組序列恢復成物件的過程.

為什麼需要序列化?

多臺機器通訊時,需要以位元組序列進行傳輸,需要將java物件序列化

當物件例項過多,要把物件儲存在硬碟中,需要的時候再讀進記憶體,也需要序列化

怎樣序列化和反序列化?

            比如序列化到硬碟檔案,再從硬碟檔案中讀取出來

         首先需要需要實現Serializable的介面,該介面沒方法,但java虛擬機器會對實現該介面的方法特殊處理,子類繼承該介面,不需要顯示宣告

         再者,jdk提供了序列化和反序列化的api

         ObjectOutputStream物件輸出流,具有writeObject方法,將物件序列化後的位元組流通過OutputStream物件寫出到檔案

         ObjectInputStream物件輸入流,有readObject()方法從一個InputStream物件中讀取位元組序列,將位元組反序列化成物件。
序列化版本號

一個類實現Serializable介面後,系統會預設給每個物件一個序列化版本號,當這個類的原始碼被修改後,系統會重新分配一個新的序列化版本號,這樣做的好處就是保證序列化和反序列化的物件內容一致。假如將一個物件序列化到硬碟之後,修改這個物件所對應類的原始碼,在進行反序列化是就會報出InvalidClassException異常。另外對於同一個類,用不同的Java編譯器編譯,有可能會導致不同的 serialVersionUID,也有可能相同,所以需要顯示定義序列號版本號

 

transient關鍵字

使用transient宣告的屬性,在序列化時將不會序列化這個屬性。

示例:

類:

import java.io.Serializable;

public class Person implements Serializable {
    //顯示宣告序列化版本號
    private static final long serialVersionUID=1467137365188219237L;
    private int stage;
    private boolean sexy;
    //transient宣告的變數不會被序列化
    transient String name;
    private int age;
    public Person(String name,int age) {
        this.name = name;
        this.age=age;
    }
    public String getName() {
        return name;
    }

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

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

序列化:

package serial;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;

public class ObjectWrite {
    public static void main(String[] args){
     Person p=new Person("小李子",17);
        ObjectOutputStream oos=null;
        try {
            oos=new ObjectOutputStream(new FileOutputStream("i:\\world\\person1"));
            //將物件序列化,寫入檔案
            oos.writeObject(p);
            //重新整理
            oos.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            try {
                if (oos!=null) {
                    oos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

反序列化:

package serial;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ObjectRead {
    public static void main(String[] args){
        ObjectInputStream ois=null;
        try {
            ois=new ObjectInputStream(new FileInputStream("i:\\world\\person1"));
            //讀取物件,從位元組中反序列化成物件
            Object obj=ois.readObject();
            Person p=(Person)obj;
            System.out.println( p.getAge()+"and"+p.getName());
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                if (ois!=null){
                    ois.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
out:
17andnull

參考:http://www.monkey1024.com/javase/641