我遇到了从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
。
答案 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);
而不是必须设置每个单独的变量。