从ObjectInputStream反序列化多个对象时出现ClassCastException

时间:2014-09-12 22:48:18

标签: java serialization classcastexception

我遇到了从ObjectInputStream反序列化多个对象的问题。我有一个名为GameSave的类,它可以做三件事:序列化对象并将它们保存到文件,删除保存文件,以及从保存文件加载对象。我有另一个类来处理GUI并调用GameSave类中的方法。这是我得到ClassCastException

的地方
p1 = (Player) GameSave.load("Mappy");
p2 = (Player) GameSave.load("Mappy");
p3 = (Player) GameSave.load("Mappy");
p4 = (Player) GameSave.load("Mappy");
map = (ArrayList<Star>) GameSave.load("Mappy"); // I am getting the error on this line

这是我GameSave课程中的代码:

public class GameSave {

public static void save(String n) {
    File saveFile = new File("saves/" + n + ".sav");
    try {
        FileOutputStream saveOut = new FileOutputStream(saveFile);
        try (ObjectOutputStream saveObj = new ObjectOutputStream(saveOut)) {
            saveObj.writeObject(Test.p1);
            saveObj.writeObject(Test.p2);
            saveObj.writeObject(Test.p3);
            saveObj.writeObject(Test.p4);
            saveObj.writeObject(Test.map);
        }
    } catch (IOException e) {
        Test.saveError.setVisible(true);
    }
}

public static void delete(String n) {
    File saveFile = new File("saves/" + n + ".sav");
    saveFile.delete();
}

public static Object load(String n) {
    try {
        FileInputStream saveIn = new FileInputStream("saves/" + n + ".sav");
        try (ObjectInputStream loadObj = new ObjectInputStream(saveIn)) {
            return loadObj.readObject();
        }
    } catch (IOException | ClassNotFoundException e) {
        Test.loadError.setVisible(true);
        return null;
    }
}
}

这是堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: com.santiago.spacegame.src.Player cannot be cast to java.util.ArrayList
at com.santiago.spacegame.src.Test.initComponents(Test.java:47)
at com.santiago.spacegame.src.Test.<init>(Test.java:23)
at com.santiago.spacegame.src.Test.lambda$main$1(Test.java:69)
at com.santiago.spacegame.src.Test$$Lambda$1/1159190947.run(Unknown Source)
at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:311)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:744)
at java.awt.EventQueue.access$400(EventQueue.java:97)
at java.awt.EventQueue$3.run(EventQueue.java:697)
at java.awt.EventQueue$3.run(EventQueue.java:691)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:75)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:714)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

即使对象按照保存顺序加载,我也会收到此错误。我确保通过GameSave保存的所有对象都会实现Serializable。有人能告诉我我做错了吗?

修改

我尝试加载这样的保存,只需调用load方法一次:

Object load = GameSave.load("Mappy");
p1 = (Player) load;
p2 = (Player) load;
p3 = (Player) load;
p4 = (Player) load;
map = (ArrayList<Star>) load;

但它仍然给了我ClassCastException

1 个答案:

答案 0 :(得分:0)

在搞清楚一些事情之后,我能够回答我自己的问题。正如蜘蛛Boris所提到的,我每次读取文件时都会打开一个新流,所以这总是会返回第一个对象Player。所以,为了解决这个问题,我将load方法更改为void,而不是为Object返回Test来处理。该方法现在看起来像这样:

public static void load(String n) {
    try {
        FileInputStream saveIn = new FileInputStream("saves/" + n + ".sav");
        try (ObjectInputStream loadObj = new ObjectInputStream(saveIn)) {
            Test.p1 = (Player) loadObj.readObject();
            Test.p2 = (Player) loadObj.readObject();
            Test.p3 = (Player) loadObj.readObject();
            Test.p4 = (Player) loadObj.readObject();
            Test.map = (ArrayList<Star>) loadObj.readObject();
        }
    } catch (IOException | ClassNotFoundException e) {
        Test.loadError.setVisible(true);
    }
}

Test中,我需要做的就是加载保存:

GameSave.load(nameOfSave);

而不是必须设置每个单独的变量。