天天看點

java序列化

java序列化

最近學習java序列化收獲頗多。談到序列化,不得不得說說為什麼需要序列化?序列化的作用是把oop程式設計中的對象轉變為位元組流然後存儲到持久化的儲存設備上。當從儲存設備上讀出這些序列化的消息并建構成對象這個過程稱為反序列化。在面向對象的程式設計中,我們經常需要存儲的不再是一些簡單的變量,而是針對對象來存儲。這在java的應用領域裡實為常見。接下來我将談談java中序列化時怎麼實作的。

首先,要序列化一個對象,必須實作java.io. serializable接口,該接口中不含有任何方法,我覺得其作用是可以統一程式設計接口一次辨別某個類可以序列化。在某些時候,我們也許并不想序列化所有的對象資料屬性,我們可以采用關鍵字transient(表明對象為一個瞬時對象)聲明,還可以把這些字段聲明為static也不會被序列化。

其次,我們要從上知道了聲明一個對象可以序列化,但究竟怎麼去實作,我們可以這樣去思考,由于我們是想把對象轉變為位元組流(序列化),以及從位元組流轉變為對象(反序列化),在java中必須實作writeobject和readobject方法,若該對象不覆寫這兩個方法将會采用java預設的方法。在此以一個執行個體進行說明:

序列化一個對象:

package com.yx.serialization;

import java.io.serializable;

publicclass serializestudent implements serializable{

    /**

     * 序列化辨別id,用于在反序列化化時使用

     * 反序列化的時候,如果記憶體中已經有了這個辨別,則認為是同一類對象

     */

    privatestaticfinallongserialversionuid = 1l;

    /*瞬時對象,不會被序列化*/

    publictransient string m_nclass=null;

    /*成員屬性*/

    private string m_studentname=null;

    public  string m_dept = null;

    public  void setstudentname(string name)

    {

          m_studentname = name;

    }

    public  void setdept(string dept)

       m_dept = dept;

    public  void setclass(string age)

            m_nclass = age;

    @override

    public string tostring()

       return"學生姓名:"+m_studentname+",系 (靜态字段):" +m_dept+",班級:(瞬時字段):"

                                                                +m_nclass;

}

序列化測試以及反序列化

import java.io.fileinputstream;

import java.io.fileoutputstream;

import java.io.ioexception;

import java.io.objectinputstream;

import java.io.objectoutputstream;

publicclass testserializable {

     * @param args

     * @throws ioexception

    publicstaticvoid main(string[] args) throws exception {

       // todo auto-generated method stub

       /*序列化的檔案路徑*/

       string filepath="e://seriable.out";

       serializestudent student = new serializestudent();

       serializestudent nstudent = new serializestudent();

       student.setstudentname("labixiaoxin");

       student.setdept("computer sicence");

       student.setclass("grade 1");

       writeobjecttest(filepath,student);

       readobjecttest(filepath);

   privatestaticvoid writeobjecttest(string filepath,object obj) throws ioexception

   {

       /*構造序列化流,也就是以流的形式寫入檔案*/

       fileoutputstream   fos = null;

       objectoutputstream oos = null;

       try {

       fos = new fileoutputstream(filepath);

       oos = new objectoutputstream(fos);

       oos.writeobject(obj);

    } catch (exception e) {

       // todo auto-generated catch block

       e.printstacktrace();

    }finally{

       if(fos!=null)

       {

           fos.close();

       }

       if(oos!=null)

           oos.close();

       //清空靜态字段,以免在後面反序列化時出現混淆

       ((serializestudent)obj).setdept(null);

   }

   privatestaticvoid readobjecttest(string filepath)

       fileinputstream    fis = null;

       objectinputstream  ois = null;

       fis = new fileinputstream(filepath);

        ois = new objectinputstream(fis);

        serializestudent obj = new serializestudent();

        obj =(serializestudent) ois.readobject();

        system.out.println("資訊:"+obj);

輸出結構:

資訊:學生姓名:labixiaoxin,系(靜态字段):null,班級:(瞬時字段):null

從輸出結構我們可以看見,靜态字段和瞬時字段為null,說明這兩個字段并未序列化,也就是并未存入我們的磁盤中去。