我知道这个问题是基本的,但我在例外情况下遇到了一些问题。
我使用ObjectOutputStream来保存计算机中的prooerties对象。不幸的是,在特殊情况下更改为类包名时,我得到了ClassNotFoundException。
我的问题很重要:
如何将旧课程中的旧属性添加到我更改的课程中?
我必须解决问题,因为我需要旧的属性来保持我的应用程序正常工作。我确定属性正确,只有类名不同。
感谢所有回复。
答案 0 :(得分:3)
有一种解决方法:
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();
答案 1 :(得分:1)
不幸的是,在特殊情况下更改为类包名称时,我得到了ClassNotFoundException
将其更改回来。您可以在不破坏现有序列的情况下更改类的许多内容,但包名称不是其中之一。您需要研究Versioning of Serializable Objects chapter of the Object Serialization Specification以了解您能够做什么和不能改变什么。在您已经完成一些序列化之后,确实在您部署应用程序之后,对包名称有了第二个想法,为时已晚。保持原状。
还有其他方法,但我希望你不需要它们。