2014-04-24 43 views
0

我創建了一個帶有兩個實現Serializable接口的int變量的簡單類。然後我爲這個類創建了對象,並在我的本地文件系統中使用ObjectOutputStream進行序列化。現在重點是序列化後,我通過刪除一個變量修改了serilized類。序列化限制

現在當我嘗試反序列化對象時,它拋出了一個名爲「java.io.InvalidClassException」的異常。

那麼有什麼辦法來限制修改序列化的類。

在java /編程術語中稱爲這種情況。

在此先感謝。

我的代碼如下:

package sample; 

import java.io.Serializable; 

public class Serial implements Serializable{ 
    int a,b; 
    public void disp(){ 
     System.out.println(a+"  "+b); 
    } 
} 


package sample; 

import java.io.FileOutputStream; 
import java.io.ObjectOutputStream; 

public class ser { 

    public static void main(String[] args) { 
     Serial ss=new Serial(); 
     ss.a=10; 
     //ss.b=20; 
     try{ 
      FileOutputStream fio=new FileOutputStream("D:\\abc.ggg"); 
      ObjectOutputStream oos=new ObjectOutputStream(fio); 
      oos.writeObject(ss); 
     } 
     catch(Exception e){ 
      e.printStackTrace(); 
     } 
    } 

} 

package sample; 

import java.io.FileInputStream; 
import java.io.ObjectInputStream; 

public class Dser { 

    public static void main(String[] args) { 
     try { 
      FileInputStream fis=new FileInputStream("D:\\abc.ggg"); 
      ObjectInputStream ois=new ObjectInputStream(fis); 
      Serial sss=(Serial)ois.readObject(); 
      sss.disp(); 
      System.out.println(sss.a+" "); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

} 
+0

請顯示相關代碼。 – mok

+0

不要忘記關閉資源 – hoaz

回答

0

每個序列化類都有一個相關的serialVersionUID。像

private static final long serialVersionUID = 1L; 

要麼你提供它,要麼JVM會在序列化類的實例時計算它。一般來說,當你修改你的班級時,你修改這個ID以便匹配班級版本。如果您不提供ID,則計算出的ID將考慮您的實例變量,因此,如果您更改了類別java.io.InvalidClassException的原因,它將會有所不同。

現在當你改變你的類,即在你的情況下刪除一個變量,你的文件中的序列化類仍然有舊的類實例。當它是反序列化的實例狀態是從文件中提取的,並嘗試使用反射注入新創建的對象。現在,當它嘗試注入已刪除的變量的值時,它將拋出異常。

0

我認爲限制改變序列化類的最好方法是通過javadoc和測試的結合。換句話說,你不能嚴格執行沒有人改變它,但你肯定可以強烈建議,除非他們想到了後果,否則他們不會。

當您將一個類序列化得比您打算成爲公共API的一部分多得多時,您會被永遠鎖定。如果你還沒有,我會建議從Josh Bloch的書「Effective Java」 - 項目74-78中查看序列化章節。他陷入了你可能遇到的無數陷阱,以及如何避免其中的很多陷阱。