2013-12-09 137 views
2

我知道這個問題是基本的,但我有一個例外的問題。objectinputstream拋出的readObject方法拋出ClassNotFoundException當更改類包

我用ObjectOutputStream來保存對象的prooerties在計算機中的對象。不幸的是,在特殊情況下,如果更改爲類包名,我會得到ClassNotFoundException。

那我的問題重要的是:

我怎麼能得到老班老樓盤爲我改變類?

我必須解決問題,因爲我需要老屬性來保持我的應用程序是work.I確保屬性是正確的,只有類名稱是不同的。

感謝所有回覆。

回答

1

不幸的是,當在特殊情況下

改回改成類包的名字,我得到的ClassNotFoundException。您可以在不破壞現有序列化的情況下更改許多關於類的信息,但程序包名稱不是其中之一。你需要研究Versioning of Serializable Objects chapter of the Object Serialization Specification,看看你能做什麼,不能做什麼改變。在已經完成一些序列化之後,事實上在部署應用程序之後,對於軟件包名稱有一些想法已經太遲了。保持它。

還有其他方法可以解決這個問題,但我希望你不需要它們。

+0

謝謝你告訴我這個信息,但我需要解決的問題。 你能告訴我如何在周圍?非常感謝你。 – user3081347

+0

我已經告訴過你如何解決這個問題。改回它。 – EJP

2

有一種變通方法:

class Workaround extends ObjectInputStream { 
    String className; 

    public Workaround(InputStream in, Class<?> cls) throws IOException { 
     super(in); 
     this.className = cls.getName(); 
    } 

    @Override 
    protected ObjectStreamClass readClassDescriptor() throws IOException, 
      ClassNotFoundException { 
     ObjectStreamClass cd = super.readClassDescriptor(); 
     try { 
      Field f = cd.getClass().getDeclaredField("name"); 
      f.setAccessible(true); 
      f.set(cd, className); 
     } catch (Exception e) { 
      throw new RuntimeException(e); 
     } 
     return cd; 
    } 
} 

現在我可以寫的Test1的實例,並把它讀作的Test2的實例

class Test1 implements Serializable { 
    private static final long serialVersionUID = 1L; 
    int i; 
} 

class Test2 implements Serializable { 
    private static final long serialVersionUID = 1L; 
    int i; 
} 

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("1")); 
Test1 test1 = new Test1(); 
oos.writeObject(test1); 
oos.close(); 
Workaround x = new Workaround(new FileInputStream("1"), Test2.class); 
Test2 test2 = (Test2)x.readObject(); 
+0

感謝您的回覆和答覆。我有幾個問題,你的方式。 是否必須存在兩個班級?因爲我改變了我的例子中的類包名,只會有一個存在。 可以做到這一點,做得好嗎? 我的英語不好很抱歉。 :) 謝謝。 – user3081347

+0

@Evgeniy Dorofeev,它完美的工作,只有對我來說它有必要改變:Field f = cd.getClass()。getDeclaredField(「name」); - > Field f = cd.getClass()。getDeclaredField(「className」); – Miguel

相關問題