将ClassCastException命中为String

时间:2013-09-04 15:58:17

标签: java deserialization classcastexception

编辑:使用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();

1 个答案:

答案 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;