编辑:使用this solution
解决我有一个非常奇怪的问题。我试图用两个已经改变的类来反序列化HashMap,尽管不是很大程度上。无法发布代码,因为它受版权保护。
值得注意的是,Class 2的构造函数有一个添加的字段(String name),因为我尝试反序列化的文件是序列化的。
似乎Class 1正在尝试将String强制转换为Class 2的名称字段。
我一直在使用ObjectInputStream和ObjectOutputStream。让我神秘化的部分是Class 1从未有过Class 2类型的成员变量,而HashMap类型总是在顺序中。我真的不知道发生了什么,所以我尝试了this question中发布的解决方案,该解决方案与我的相同,但是尽管有很多关于ClassLoaders的研究,我仍然不太了解并且没有我真的知道使用什么ClassLoader作为“自由变量”。
以下是我遇到的问题的堆栈跟踪(类名已更改):
java.lang.ClassCastException: cannot assign instance of [CLASS 1] to field [CLASS 2].name of type java.lang.String in instance of [CLASS 2]
at java.io.ObjectStreamClass$FieldReflector.setObjFieldValues(ObjectStreamClass.java:2034)
at java.io.ObjectStreamClass.setObjFieldValues(ObjectStreamClass.java:1207)
at java.io.ObjectInputStream.defaultReadFields(ObjectInputStream.java:1975)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1893)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1775)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1327)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:349)
at java.util.HashMap.readObject(HashMap.java:1030)
at sun.reflect.GeneratedMethodAccessor27.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeReadObject(ObjectStreamClass.java:969)
at java.io.ObjectInputStream.readSerialData(ObjectInputStream.java:1871)
at java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1775)
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1327)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:349)
代码片段:
final ClassLoader loader = this.getClass().getClassLoader(); //attempt to solve ClassCastException issue below.
FileInputStream fin = new FileInputStream(targetFile);
InputStream buffer = new BufferedInputStream(fin);
ObjectInputStream ois = new ObjectInputStream(buffer) {
/*
* As seen here: https://stackoverflow.com/questions/2358886/how-can-i-deserialize-the-object-if-it-was-moved-to-another-package-or-renamed
*/
@Override
protected ObjectStreamClass readClassDescriptor() throws IOException, ClassNotFoundException {
ObjectStreamClass resultClassDescriptor = super.readClassDescriptor();
if (resultClassDescriptor.getName().equals("Class 1 [old path]"))
resultClassDescriptor = ObjectStreamClass.lookup(Class 1 [new path].class);
else if (resultClassDescriptor.getName().equals("Class 2 [old path]"))
resultClassDescriptor = ObjectStreamClass.lookup(Class 2 [new path].class);
return resultClassDescriptor;
}
/*
* As seen here : https://stackoverflow.com/questions/9110677/readresolve-not-working-an-instance-of-guavas-serializedform-appears
*/
@SuppressWarnings("rawtypes")
@Override
protected Class resolveClass(ObjectStreamClass objectStreamClass)
throws IOException, ClassNotFoundException {
return Class.forName(objectStreamClass.getName(), true, loader);
}
};
Object ob = ois.readObject(); //exception happens here
HashMap<Class 1, Class 2> loadedMap = (HashMap<Class 1, Class 2>)ob;
ois.close();
buffer.close();
fin.close();
答案 0 :(得分:0)
看起来您正在分配两个不兼容的类。
class_1 = new class_2()
class_1必须是class_2的class_2或superclass。 似乎
resultClassDescriptor = ObjectStreamClass.lookup(Class 2 [new path].class);
可能是罪魁祸首。 // ...................编辑
class A{}
class B extends A{}
class C{}
A obj = new B();
,不会出错,因为A是B的超类。
如果你将obj
强制转换为C类,那么它将抛出ClassCastException
C cobj =(C)obj;