序列化流(ObjectOutputStream、ObjectInputStream)
- 2020 年 8 月 18 日
- 筆記
- JAVA, Java 序列化 反序列化
1、序列化流(ObjectOutputStream)
1 package demo10.objstream; 2 3 /* 4 java.io.ObjectOutputStream extends OutputStream 5 ObjectOutputStream:對象的序列化流 6 作用:把對象以流的方式寫入到文件中保存 7 8 構造方法: 9 ObjectOutputStream(OutputStream out) 創建寫入指定 OutputStream 的 ObjectOutputStream。 10 參數: 11 OutputStream out:位元組輸出流 12 特有的成員方法: 13 void writeObject(Object obj) 將指定的對象寫入 ObjectOutputStream。 14 15 使用步驟: 16 1.創建ObjectOutputStream對象,構造方法中傳遞位元組輸出流 17 2.使用ObjectOutputStream對象中的方法writeObject,把對象寫入到文件中 18 3.釋放資源 19 */ 20 21 import java.io.FileNotFoundException; 22 import java.io.FileOutputStream; 23 import java.io.IOException; 24 import java.io.ObjectOutputStream; 25 26 public class demo01objout { 27 public static void main(String[] args) throws IOException { 28 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("obj.txt")); 29 Person p=new Person("kelvin",18); 30 oos.writeObject(p); 31 oos.close(); 32 } 33 }
2、反序列化流(ObjectInputStream)
1 package demo10.objstream; 2 3 /* 4 java.io.ObjectInputStream extends InputStream 5 ObjectInputStream:對象的反序列化流 6 作用:把文件中保存的對象,以流的方式讀取出來使用 7 8 構造方法: 9 ObjectInputStream(InputStream in) 創建從指定 InputStream 讀取的 ObjectInputStream。 10 參數: 11 InputStream in:位元組輸入流 12 特有的成員方法: 13 Object readObject() 從 ObjectInputStream 讀取對象。 14 15 使用步驟: 16 1.創建ObjectInputStream對象,構造方法中傳遞位元組輸入流 17 2.使用ObjectInputStream對象中的方法readObject讀取保存對象的文件 18 3.釋放資源 19 4.使用讀取出來的對象(列印) 20 21 readObject方法聲明拋出了ClassNotFoundException(class文件找不到異常) 22 當不存在對象的class文件時拋出此異常 23 反序列化的前提: 24 1.類必須實現Serializable 25 2.必須存在類對應的class文件 26 */ 27 28 import java.io.*; 29 30 public class demo01objin { 31 public static void main(String[] args) throws IOException, ClassNotFoundException { 32 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("obj.txt")); 33 Object o = ois.readObject(); 34 ois.close(); 35 Person p = (Person) o; 36 System.out.println(p.getName() + " " + p.getAge()); 37 } 38 }
Person類
1 package demo10.objstream; 2 3 import java.io.Serializable; 4 5 /* 6 序列化和反序列化的時候,會拋出NotSerializableException沒有序列化異常 7 類通過實現 java.io.Serializable 介面以啟用其序列化功能。未實現此介面的類將無法使其任何狀態序列化或反序列化。 8 Serializable介面也叫標記型介面 9 要進行序列化和反序列化的類必須實現Serializable介面,就會給類添加一個標記 10 當我們進行序列化和反序列化的時候,就會檢測類上是否有這個標記 11 有:就可以序列化和反序列化 12 沒有:就會拋出 NotSerializableException異常 13 14 15 static關鍵字:靜態關鍵字 16 靜態優先於非靜態載入到記憶體中(靜態優先於對象進入到記憶體中) 17 被static修飾的成員變數不能被序列化的,序列化的都是對象 18 private static int age; 19 oos.writeObject(new Person("kelvin",18)); 20 Object o = ois.readObject(); 21 Person{name='kelvin', age=0} 22 23 transient關鍵字:瞬態關鍵字 24 被transient修飾成員變數,不能被序列化 25 private transient int age; 26 oos.writeObject(new Person("kelvin",18)); 27 Object o = ois.readObject(); 28 Person{name='kelvin', age=0} 29 30 */ 31 32 public class Person implements Serializable { 33 private String name; 34 private int age; 35 36 public Person() { 37 } 38 39 public Person(String name, int age) { 40 this.name = name; 41 this.age = age; 42 } 43 44 @Override 45 public String toString() { 46 return "Person{" + 47 "name='" + name + '\'' + 48 ", age=" + age + 49 '}'; 50 } 51 52 public String getName() { 53 return name; 54 } 55 56 public void setName(String name) { 57 this.name = name; 58 } 59 60 public void setAge(int age) { 61 this.age = age; 62 } 63 64 public int getAge() { 65 return age; 66 } 67 }
# 注:在序列化對象時,由於該對象所屬的類實現了Serializable介面,所以該類在編譯時會在.class文件中保存SerialVersionUID=xxx標識,如果類定義發生改變,SerialVersionUID也會改變。並且序列化對象時,內部會攜帶該標識,當反序列化時候,判斷如果反序列化的對象內部的SerialVersionUID和.class文件內部保存的SerialVersionUID相同反序列化成功,否則拋出InvalidClassException異常。 解決方式: 在定義類時候手動定義SerialVersionUID。 格式為:private static final long serialVersionUID=xxL
3、練習(序列化集合)
1 package demo10.objstream; 2 3 import java.io.*; 4 import java.util.ArrayList; 5 6 public class test { 7 public static void main(String[] args) throws IOException, ClassNotFoundException { 8 // output(); 9 input(); 10 } 11 12 private static void input() throws IOException, ClassNotFoundException { 13 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("list.txt")); 14 Object o = ois.readObject(); 15 ArrayList<Person> list = (ArrayList) o; 16 for (Person person : list) { 17 System.out.println(person); 18 } 19 ois.close(); 20 21 } 22 23 private static void output() throws IOException { 24 ArrayList<Person> list = new ArrayList<>(); 25 list.add(new Person("kelvin", 23)); 26 list.add(new Person("jack", 18)); 27 list.add(new Person("siri", 34)); 28 29 ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("list.txt")); 30 oos.writeObject(list); 31 oos.close(); 32 } 33 }