Java 之 ObjectInputStream 類


ObjectInputStream 類

  1、概述

      java.io.ObjectInputStream extends InputStream

    ObjectInputStream 反序列化流,將之前使用 ObjectOutputStream 序列化的原始數據恢復為對象,以流的方式讀取對象。 

  2、構造方法

ObjectInputStream(InputStream in) 創建從指定 InputStream 讀取的 ObjectInputStream。

    參數:InputStream in:字節輸入流

  3、特有的成員方法

Object readObject() 從 ObjectInputStream 讀取對象。

  

  4、使用步驟

    ① 創建ObjectInputStream對象,構造方法中傳遞字節輸入流

    ② 使用ObjectInputStream對象中的方法readObject讀取保存對象的文件

    ③ 釋放資源

    ④ 使用讀取出來的對象(打印)

  5、注意

     readObject方法聲明拋出了ClassNotFoundException(class文件找不到異常)

    當不存在對象的 class 文件時拋出此異常:

    反序列化的前提:

      ① 類必須實現 Seriaizable 

      ② 必須存在類對應的 class 文件

  6、反序列化操作1

    如果能找到一個對象的class文件,可以進行反序列化操作,調用 ObjectInputStream 讀取對象的方法:

public final Object readObject () : 讀取一個對象。

      Demo:

 1 public static void main(String [] args) {  2     Employee e = null;  3     try {  4         // 創建反序列化流
 5         FileInputStream fileIn = new FileInputStream("employee.txt");  6         ObjectInputStream in = new ObjectInputStream(fileIn);  7         // 讀取一個對象
 8         e = (Employee) in.readObject();  9         // 釋放資源
10  in.close(); 11  fileIn.close(); 12     }catch(IOException i) { 13         // 捕獲其他異常
14  i.printStackTrace(); 15        return; 16     }catch(ClassNotFoundException c) { 17         // 捕獲類找不到異常
18         System.out.println("Employee class not found"); 19  c.printStackTrace(); 20         return; 21  } 22         // 無異常,直接打印輸出
23  System.out.println(e); 24 
25  } 26 }

 

  對於JVM可以反序列化對象,它必須是能夠找到class文件的類。如果找不到該類的class文件,則拋出一個ClassNotFoundException 異常。

  7、反序列化操作2

    JVM反序列化對象時,能找到class文件,但是class文件在序列化對象之后發生了修改,那么反序列化操作也會失敗,拋出一個 InvalidClassException 異常。 

    原因如下

      ① 該類的序列版本號與從流中讀取的類描述符的版本號不匹配

      ② 該類包含未知數據類型

      ③ 該類沒有可訪問的無參數構造方法

      Serializable 接口給需要序列化的類,提供了一個序列版本號serialVersionUID 該版本號的目的在於驗證序列化的對象和對應類是否版本匹配。

    解決方法:

      ① 修改本地的serialVersionUID為流中的serialVersionUID

      ② 在當初實現Serializable接口時,就固定一個serialVersionUID,這樣每次編譯就不會自動生成一個新的serialVersionUID

    Demo:

 1 public class Employee implements java.io.Serializable {  2     // 加入序列版本號
 3     private static final long serialVersionUID = 1L;  4     public String name;  5     public String address;  6     // 添加新的屬性 ,重新編譯, 可以反序列化,該屬性賦為默認值.
 7     public int eid;  8     public void addressCheck() {  9         System.out.println("Address check : " + name + " ‐‐ " + address); 10  } 11 }

   序列號沖突異常的原理和解決方案:

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM