2013-12-09 88 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

相关问题