1. 程式人生 > 其它 >Java-IO流系列-物件流

Java-IO流系列-物件流

物件流

物件流的介紹

  • ObjectInputStream和OjbectOutputSteam

  • 用於儲存和讀取基本資料型別資料或物件的處理流。它的強大之處就是可以把Java中的物件寫入到資料來源中,也能把物件從資料來源中還原回來。

  • 序列化:用ObjectOutputStream類儲存基本型別資料或物件的機制

  • 反序列化:用ObjectInputStream類讀取基本型別資料或物件的機制

  • ObjectOutputStream和ObjectlnputStream不能序列化static和transient修飾的成員變數

  • 凡是實現Serializable介面的類都有一個表示序列化版本識別符號的靜態變數:

    • private static final long serialVersionUID;
    • serialVersionUID用來表明類的不同版本間的相容性。簡言之,其目的是以序列化物件進行版本控制,有關各版本反序列化時是否相容。
    • 如果類沒有顯示定義這個靜態變數,它的值是Java執行時環境根據類的內部細節自動生成的。若類的例項變數做了修改,serialVersionUID 可能發生變化。故建議,顯式宣告。
  • 簡單來說,Java的序列化 機制是通過在執行時判斷類的serialVersionUID來驗證版本一致性的。在進行反序列化時,JVM會把傳來的位元組流中的serialVersionUID與木地相應實體類的serialVersionUID進行比較,如果相同就認為是一致的,可以進行反序列化,否則就會出現序列化版本不一致的異
    常。(InvalidCastException)

物件的序列化機制

  • 物件序列化機制允許把記憶體中的Java物件轉換成平臺無關的:二進位制流,從而允許把這種二進位制流持久地儲存在磁碟上,或通過網路將這種二進位制流傳輸到另一個網路節點。當其它程式獲取了這種二進位制流,就可以恢復成原來的Java物件

  • 序列化的好處在於可將任何實現了Serializable介面的物件轉化為位元組資料,使其在儲存和傳輸時可被還原

  • 序列化是RMI ( Remote Method Invoke -遠端方法呼叫)過程的引數和返回值都必須實現的機制,而RMI是JavaEE的基礎。因此序列化機制是JavaEE平臺的基礎

  • 如果需要讓某個物件支援序列化機制,則必須讓:物件所屬的類及其屬性是可序列化的,為了讓某個類是可序列化的,該類必須實現如下兩個介面之一。否則,會丟擲NotSerializableException異常

樣例

序列化過程

序列化過程:將記憶體中的java物件儲存到磁碟中或通過網路傳輸出去使用0bjectoutputstream實現

package com.dreamcold.io;

import java.io.*;

public class Demo18 {
    public static void main(String[] args) throws IOException {
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("object.dat"));
        oos.writeObject(new String("dreamcold"));
        oos.flush();
        oos.close();
    }
}

反序列化過程

package com.dreamcold.io;

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

public class Demo19 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("object.dat"));
        Object obj=ois.readObject();
        String str=(String)obj;
        System.out.println(str);
        ois.close();

    }
}

效果:

自定義物件序列化

Main.java

package com.dreamcold.io;

import java.io.*;

public class Demo18 {
    public static void main(String[] args) throws IOException {
        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("object.dat"));
        Person person=new Person("dreamcold",21);
        oos.writeObject(person);
        oos.flush();
        oos.close();
    }
}

Person.java

package com.dreamcold.io;

public class Person {
     private String name;
     private Integer age;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

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

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

執行結果

要讓物件可以被序列化要讓物件的類實現對應的Serializable介面,Serializable介面是標識介面

Person需要滿足如下的要求,方可序列化

  1. 需要實現介面: Serializable
  2. 當前類提供一個全域性常量: serialversionUId
  3. ,除了當前Person類需要實現Serializable介面之外, 還必須保證其內部所有屬性也必須是可序列化的。(預設我們的基本資料是可以序列化的)
package com.dreamcold.io;

import java.io.Serializable;

public class Person implements Serializable {

     private String name;
     private Integer age;
     public static final long serialVersionUID = -6849794470754662210L;

    public Person(String name, Integer age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

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

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

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

讀取:

package com.dreamcold.io;

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

public class Demo19 {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("object.dat"));
        Object obj=ois.readObject();
        Person person=(Person)obj; 
        System.out.println(person);
        ois.close();

    }
}

效果: