ObjectOutputStream 類
1、概述
java.io.ObjectOutputStream extends OutputStream
ObjectOutputStream:對象的序列化流,作用:把對象轉成字節數據的輸出到文件中保存,對象的輸出過程稱為序列化,可實現對象的持久存儲。
2、構造方法
ObjectOutputStream(OutputStream out) 創建寫入指定 OutputStream 的 ObjectOutputStream。
參數:OutputStream out:字節輸出流
3、特有的成員方法
void writeObject(Object obj) 將指定的對象寫入 ObjectOutputStream。
writeObject 方法用於將對象寫入流中。所有對象(包括 String 和數組)都可以通過 writeObject 寫入。
可將多個對象或基元寫入流中。必須使用與寫入對象時相同的類型和順序從相應 ObjectInputstream 中讀回對象。
4、使用步驟
① 創建ObjectOutputStream對象,構造方法中傳遞字節輸出流
② 使用ObjectOutputStream對象中的方法writeObject,把對象寫入到文件中
③ 釋放資源
5、序列化操作
一個對象要想序列化,必須滿足兩個條件
① 該類必須實現 java.io.Serializable 接口, Serializable 是一個標記接口,不實現此接口的類將不會使任何狀態序列化或反序列化,會拋出 NotSerializableException 。
每個 serializable 對象的類都被編碼,編碼內容包括類名和類簽名、對象的字段值和數組值,以及從初始對象中引用的其他所有對象的閉包。
② 該類的所有屬性必須是可序列化的。如果有一個屬性不需要可序列化的,則該屬性必須注明是瞬態的,使用transient 關鍵字修飾。
Demo:
1 public class Person implements Serializable{ // 實現序列化接口 2 private static final long serialVersionUID = 1L; 3 private String name; 4 private int age; 5
6 public Person() { 7 } 8
9 public Person(String name, int age) { 10 this.name = name; 11 this.age = age; 12 } 13
14 @Override 15 public String toString() { 16 return "Person{" +
17 "name='" + name + '\'' +
18 ", age=" + age +
19 '}'; 20 } 21
22 public String getName() { 23 return name; 24 } 25
26 public void setName(String name) { 27 this.name = name; 28 } 29
30 public int getAge() { 31 return age; 32 } 33
34 public void setAge(int age) { 35 this.age = age; 36 } 37 } 38 public static void main(String[] args) throws IOException { 39 //1.創建ObjectOutputStream對象,構造方法中傳遞字節輸出流
40 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\person.txt")); 41 //2.使用ObjectOutputStream對象中的方法writeObject,把對象寫入到文件中
42 oos.writeObject(new Person("張三",18)); 43 //3.釋放資源
44 oos.close(); 45 }
注意:
① 序列化和反序列化的時候,會拋出NotSerializableException不能序列化異常
② 類通過實現 java.io.Serializable 接口以啟用其序列化功能。未實現此接口的類將無法使其任何狀態序列化或反序列化。
③ Serializable接口也叫標記型接口,要進行序列化和反序列化的類必須實現Serializable接口,就會給類添加一個標記
④ 當進行序列化時會檢查是否有這個標記,有:就可以序列化和反序列化;沒有:就會拋出 NotSerializableException異常
Static 關鍵字:靜態關鍵字
靜態優先於非靜態加載到內存中(靜態優先於對象進入到內存中)
被static修飾的成員變量不能被序列化的,因為靜態的變量不屬於某個對象,而是整個類的,所以不需要隨着對象的序列化而序列化。序列化的都是對象
如果上面的 Person類中的 age 聲明為:private static int age;這時再對 Person 這個對象序列化時,age 始終為0,不能被序列化。
transient 關鍵字:瞬態關鍵字
被transient修飾成員變量,不能被序列化
Demo:
1 private transient int age; 2 oos.writeObject(new Person("張三",18)); 3 Object o = ois.readObject(); 4 Person{name='張三', age=0}
注意:
序列化一個對象時,要求它的屬性要么是基本數據類型,如果是引用數據類型,這個引用數據類型也必須實現Serializable接口。
序列化一個數組,要求元素類型實現Serializable接口。