java序列化流:序列化與逆序列化
阿新 • • 發佈:2018-11-27
package com.qianfeng.test; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; /* * 序列化流:將短期儲存的資料實現長期儲存的過程 * * 短期儲存:資料存放在記憶體中,資料會隨著程式的關閉而釋放----物件,陣列,集合,變數 * 長期儲存:資料存放在磁碟中,即使程式關閉了,資料依然存在----檔案 * * 序列化:將資料從記憶體存入磁碟,可以實現資料的持久化儲存. * 逆序列化:將資料從磁碟傳回記憶體. * * 進行序列化的步驟:---以物件的序列化為例項講解 * 1.建立一個類 * 2.使用對應的流將物件存入磁碟---序列化---ObjectOutputStream * 3.使用對應的流將資料從磁碟中取出放回記憶體---逆序列化-----ObjectInputStream * 4.關閉流 * * 注意:序列化流在工作時也要關聯輸入流和輸出流 * //建立類用於序列化 //類通過實現 java.io.Serializable 介面以啟用其序列化功能。未實現此介面的類將無法使其任何狀態序列化或反序列化。 //可序列化類的所有子型別本身都是可序列化的。序列化介面沒有方法或欄位,僅用於標識可序列化的語義。 /* * 解釋: * 一個類如果沒有實現Serializable,進行序列化會報異常:NotSerializableException * * 實現了Serializable介面的類可以達到的目的: * 1.可以進行序列化 * 2.進行序列化的類的元素都必須支援序列化 * 3.介面本身沒有方法或欄位,只是用來表示可序列化的語義 * * * 注意點: * 1. ClassNotFoundException:當前的類沒有找到 * 分析:將Person物件進行序列化之後,將Person類刪除,再進行反序列化的時候出現了異常 * 原因:反序列化在執行的時候依賴位元組碼檔案,當類沒有了,位元組碼檔案無法建立,反序列化失敗 * * 2.java.io.InvalidClassException 無效的類 * 出現的原因:沒有宣告自己的serialVersionUID,而使用系統的.在進行反序列化的時候,類被改動了,系統認為現在的類 * 已經不是原來的類了(在使用系統的id進行識別的時候,重寫給Person設定了id),認為此類無效 * * 3.使用系統的serialVersionUID與自定義的ID的區別? * 使用系統的,序列化和反序列化,id不能手動設定,使用的是編譯器預設生成的,一旦類發生了改動,id會重新賦值 * 使用自定義的,序列化和反序列化,id不會發生改變,所以當反序列化的時候,即使對Person類進行了一些改動,也能繼續反序列化 * * 4.總結序列化,反序列化工程的注意點: * a.合理使用序列化流和反序列化流,要與輸入流與輸出流配合使用 * b.進行序列化的類一定要實現Serializable介面,只要實現了介面就可以序列化.包括集合,包裝類等 * c.進行序列化的類要保證當前類與內部的類都要實現Serializable介面 * */ public class Demo11 { public static void main(String[] args) throws FileNotFoundException, IOException, ClassNotFoundException { //序列化 fun1(); //逆序列化 fun2(); } //序列化 public static void fun1() throws FileNotFoundException, IOException{ //建立序列化流並關聯檔案 ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("temp4.txt")); //實現序列化 //注意:序列化後得到的內容不能直接檢視,要看必須經過逆序列化 objectOutputStream.writeObject(new Person("bingbing",20)); //關閉流 objectOutputStream.close(); } //逆序列化 public static void fun2() throws FileNotFoundException, IOException, ClassNotFoundException { //建立逆序列化流並關聯檔案 ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("temp4.txt")); //實現逆序列化--讀 Object object = objectInputStream.readObject(); Person person = (Person)object; System.out.println(person); //關閉流 objectInputStream.close(); } } //建立一個類 //這個類的物件要想進行序列化必須實現Serializable介面. //類通過實現Serializable介面啟動序列化功能.未實現此介面的類無法實現序列化或逆序列化. //如果沒有實現Serializable,會報異常NoSerializableException //注意點:可序列化的物件的內部的元素也要都支援序列化. class Person implements Serializable{ /** * generated:由編譯器自動生成的,後面加L表示long型資料 * * */ private static final long serialVersionUID = 9100147150931711124L; // /** // * default:預設的方式,可以由使用者自己指定,預設值是1L // */ // private static final long serialVersionUID = 17489587495847L; String name; int age; //int height; public Person(String name, int age) { super(); this.name = name; this.age = age; } public Person() { super(); } @Override public String toString() { return "Person [name=" + name + ", age=" + age + "]"; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }