2014-09-12 66 views
0

我在從ObjectInputStream反序列化多個對象時遇到問題。我有一個名爲GameSave的類,它可以做3件事:序列化對象並將其保存到文件,刪除保存文件以及從保存文件加載對象。我有另一個類來處理GUI並調用GameSave類中的方法。這是我得到一個ClassCastException從ObjectInputStream反序列化多個對象時發生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

您的寫入方法將所有內容寫入同一個流 - 這很好。您的讀取方法每次都會打開一個流 - 這意味着您每次都讀取同一個對象,即第一個對象。因此,當您嘗試將其讀入「List」時,您會看到一個錯誤。 – 2014-09-12 22:51:57

+0

向我們展示您的課堂測試。順便說一句,看起來你的對象映射是ArrayList類型的,並且你試圖將它轉換爲Player。 – 2014-09-12 22:53:11

+0

@BoristheSpider,哈哈,我明白你的意思了。我是否需要在我的類「Test」(GUI類)中創建一個「Object」的新實例,然後將其轉換爲我的特定類型? – 2014-09-12 22:54:42

回答

0

找出一些事情後,我能夠回答我自己的問題。正如Boris the Spider所提到的,每當我讀取文件時,我都會打開一個新流,因此它總是返回第一個對象,即Player。所以,爲了解決這個問題,我將我的加載方法更改爲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); 

,而不必設置每個變量。