【JAVA IO】_對象序列化筆記

來源:互聯網
上載者:User

【JAVA IO】_對象序列化筆記

本章目標:
掌握對象序列化的作用
掌握Serializable介面作用
可以使用ObjectOutputStream進行對象序列化操作
可以使用ObjectinputStream進行對象還原序列化操作
掌握Externalizable介面的作用及與Serializable介面的實現區別
掌握transient關鍵字的作用
可以序列化一組對象

3.1、什麼叫對象序列化

一個對象產生後實際上是在記憶體中為其開闢了一個儲存空間,方便儲存資訊。

對象序列化,就是把一個對象變為二進位的資料流的一種方法,通過對象序列化可以方便的實現對象的傳輸或儲存.

如果一個類的對象想被序列化,則對象所在的類必須實現java.io.Serializable介面。此介面定義如下:

public interface Serializable{}

一個類不能平白無故的被序列化。

但是,在此介面中沒有任何一個方法,此介面屬於一個標識介面,表示具備了某種能力。

例如:現在定義一個類,此類可以被序列化。

import java.io.Serializable;public class Person implements Serializable{    private String name;    private int age;    public Person(String name,int age){        this.name = name;        this.age = age;        }    public String toString(){        return "姓名:"+this.name+";年齡:"+this.age;        }}

以後此類的對象,就可以被序列化了,變為二進位byte流。

對象的序列化和還原序列化
要想完成對象的輸入或輸出,還必須依靠對象輸出資料流(ObjectOutputStream)和對象輸入資料流(ObjectInputStream)
使用對象輸出資料流輸出序列化對象的步驟,有時也稱之為序列化,而使用對象輸入資料流讀入對象的過程,有時也稱為還原序列化。

serialVersionUID
對象的序列化和還原序列化要考慮JDK版本不統一的問題,所以在序列化操作中引入了serialVersionUID的常量,可以通過此常量來驗證版本的一致性,在進行還原序列化時,JVM會把傳來的位元組流中的serialVersionUID與本地的相應實體類的serialVersionUID進行比較,如果相同就認為是一致的,可以進行還原序列化,否則就會出現序列化版本不一致的異常。

import java.io.Serializable;public class Person implements Serializable{    private static final long serialVersionUID = 1L;    private String name;    private int age;    public Person(String name,int age){        this.name = name;        this.age = age;        }    public String toString(){        return "姓名:"+this.name+";年齡:"+this.age;        }}

如果使用開發工具開發,就有編寫此代碼,則會出現一些安全警告的資訊。

3.2、對象的序列化及還原序列化操作
對象序列化依靠ObjectOutputStream,對象還原序列化依靠ObjectInputStream

3.2.1、序列化:ObjectOutputStream

定義格式:
public class ObjectOutputStream extends OutputStream implements ObjectOutput,ObjectStreamConstants

import java.io.File ;import java.io.FileOutputStream ;import java.io.OutputStream ;import java.io.ObjectOutputStream ;public class SerDemo01{    public static void main(String args[]) throws Exception {        File f = new File("D:" + File.separator + "test.txt") ;    // 定義儲存路徑        ObjectOutputStream oos = null ;    // 聲明對象輸出資料流        OutputStream out = new FileOutputStream(f) ;    // 檔案輸出資料流        oos = new ObjectOutputStream(out) ;        oos.writeObject(new Person("張三",30)) ;    // 儲存對象        oos.close() ;    // 關閉    }};

到底序列化了哪些東西呢?

所有的對象擁有各自的屬性值,但是所有的方法都是公用的,所以序列化對象的時候實際上序列化的就是屬性。

3.2.2、還原序列化:ObjectInputStream

定義格式
public class ObjectInputStream extends InputStream implements ObjectInput,ObjectStreamConstants

import java.io.File ;import java.io.FileInputStream ;import java.io.InputStream ;import java.io.ObjectInputStream ;public class SerDemo02{    public static void main(String args[]) throws Exception {        File f = new File("D:" + File.separator + "test.txt") ;    // 定義儲存路徑        ObjectInputStream ois = null ;    // 聲明對象輸入資料流        InputStream input = new FileInputStream(f) ;    // 檔案輸入資料流        ois = new ObjectInputStream(input) ;    // 執行個體化對象輸入資料流        Object obj = ois.readObject() ;    // 讀取對象        ois.close() ;    // 關閉        System.out.println(obj) ;    }};

問題:如果一個類實現了Serializable介面,則肯定此類可以被序列化下來,那麼也就意味著此類多了一項功能,可以被序列化,那麼讓所有類都實現此介面是不是更好啊?
因為:JDK是會不斷升級的,現在Serializable介面中沒有任何定義,那麼以後呢?

3.3、Externalizable介面

使用Serializable介面可以方便的序列化一個對象,但是在序列化操作中也提供了另外一種序列化機制————Exnternalizable介面

定義格式:
public interface Externalizable extends Serializable{
    public void writeExternal(ObjectOutput out)throws IOException;
    public void readExternal(ObjectInput in)throws IOException,ClassNotFoundException;
}

在使用Exterlizable介面的時候需要在被序列化的類中定義一個無參構造。

import java.io.Externalizable;import java.io.*;public class Person implements Externalizable{    private static final long serialVersionUID = 1L;    private String name;    private int age;    public Person(){}    public Person(String name,int age){        this.name = name;        this.age = age;        }    public String toString(){        return "姓名:"+this.name+";年齡:"+this.age;        }    public void writeExternal(ObjectOutput out)throws IOException{        out.writeObject(this.name);        out.writeInt(this.age);    }    public void readExternal(ObjectInput in)throws IOException,ClassNotFoundException{        this.name = (String)in.readObject();        this.age = in.readInt();    }}

import java.io.File ;import java.io.IOException ;import java.io.FileOutputStream ;import java.io.OutputStream ;import java.io.ObjectOutputStream ;import java.io.FileInputStream ;import java.io.InputStream ;import java.io.ObjectInputStream ;public class SerDemo03{    public static void main(String args[]) throws Exception{        //ser() ;        dser() ;    }    public static void ser() throws Exception {        File f = new File("D:" + File.separator + "test.txt") ;    // 定義儲存路徑        ObjectOutputStream oos = null ;    // 聲明對象輸出資料流        OutputStream out = new FileOutputStream(f) ;    // 檔案輸出資料流        oos = new ObjectOutputStream(out) ;        oos.writeObject(new Person("張三",30)) ;    // 儲存對象        oos.close() ;    // 關閉    }    public static void dser() throws Exception {        File f = new File("D:" + File.separator + "test.txt") ;    // 定義儲存路徑        ObjectInputStream ois = null ;    // 聲明對象輸入資料流        InputStream input = new FileInputStream(f) ;    // 檔案輸入資料流        ois = new ObjectInputStream(input) ;    // 執行個體化對象輸入資料流        Object obj = ois.readObject() ;    // 讀取對象        ois.close() ;    // 關閉        System.out.println(obj) ;    }};

3.4、transient關鍵字

當使用Serializable介面實現序列化操作時,如果一個對象中的某個屬性不希望被序列化的話,則可以使用transient關鍵字進行聲明。

import java.io.Serializable;public class Person implements Serializable{    private static final long serialVersionUID = 1L;    private transient String name;    private int age;    public Person(String name,int age){        this.name = name;        this.age = age;        }    public String toString(){        return "姓名:"+this.name+";年齡:"+this.age;        }}

import java.io.File ;import java.io.IOException ;import java.io.FileOutputStream ;import java.io.OutputStream ;import java.io.ObjectOutputStream ;import java.io.FileInputStream ;import java.io.InputStream ;import java.io.ObjectInputStream ;public class SerDemo04{    public static void main(String args[]) throws Exception{        ser() ;        dser() ;    }    public static void ser() throws Exception {        File f = new File("D:" + File.separator + "test.txt") ;    // 定義儲存路徑        ObjectOutputStream oos = null ;    // 聲明對象輸出資料流        OutputStream out = new FileOutputStream(f) ;    // 檔案輸出資料流        oos = new ObjectOutputStream(out) ;        oos.writeObject(new Person("張三",30)) ;    // 儲存對象        oos.close() ;    // 關閉    }    public static void dser() throws Exception {        File f = new File("D:" + File.separator + "test.txt") ;    // 定義儲存路徑        ObjectInputStream ois = null ;    // 聲明對象輸入資料流        InputStream input = new FileInputStream(f) ;    // 檔案輸入資料流        ois = new ObjectInputStream(input) ;    // 執行個體化對象輸入資料流        Object obj = ois.readObject() ;    // 讀取對象        ois.close() ;    // 關閉        System.out.println(obj) ;    }};

transient+Serializable介面完全可以取代Externalizable介面的功能。

3.5、序列化一組對象(就是將Obj由單個對象變為多個對象)

import java.io.File ;import java.io.IOException ;import java.io.FileOutputStream ;import java.io.OutputStream ;import java.io.ObjectOutputStream ;import java.io.FileInputStream ;import java.io.InputStream ;import java.io.ObjectInputStream ;public class SerDemo05{    public static void main(String args[]) throws Exception{        Person per[] = {new Person("張三",30),new Person("李四",31),            new Person("王五",32)} ;        ser(per) ;        Object o[] = (Object[])dser() ;        for(int i=0;i<o.length;i++){            Person p = (Person)o[i] ;            System.out.println(p) ;        }    }    public static void ser(Object obj[]) throws Exception {        File f = new File("D:" + File.separator + "test.txt") ;    // 定義儲存路徑        ObjectOutputStream oos = null ;    // 聲明對象輸出資料流        OutputStream out = new FileOutputStream(f) ;    // 檔案輸出資料流        oos = new ObjectOutputStream(out) ;        oos.writeObject(obj) ;    // 儲存對象        oos.close() ;    // 關閉    }    public static Object[] dser() throws Exception {        File f = new File("D:" + File.separator + "test.txt") ;    // 定義儲存路徑        ObjectInputStream ois = null ;    // 聲明對象輸入資料流        InputStream input = new FileInputStream(f) ;    // 檔案輸入資料流        ois = new ObjectInputStream(input) ;    // 執行個體化對象輸入資料流        Object obj[] = (Object[])ois.readObject() ;    // 讀取對象        ois.close() ;    // 關閉        return obj ;    }};

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.