2014-09-12 3 views
0

У меня возникла проблема с десериализацией нескольких объектов из ObjectInputStream. У меня есть класс под названием GameSave, который может делать 3 вещи: сериализовывать объекты и сохранять их в файл, удалять файл сохранения и загружать объекты из файла сохранения. У меня есть еще один класс, который обрабатывает GUI и вызывает методы в классе GameSave. Это где я получаю ClassCastException:ClassCastException при десериализации нескольких объектов из ObjectInputStream

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. Может ли кто-нибудь сказать мне, что я делаю неправильно?

EDIT:

Я попытался загрузки сохранения, как это, лишь вызвав метод 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

Покажите нам свой тест класса. Кстати, похоже, ваша карта объектов имеет тип ArrayList, и вы пытаетесь передать ее в Player. –

+0

@BoristheSpider, ага, я понимаю, что вы имеете в виду. Должен ли я создать новый экземпляр объекта «Объект» в классе «Тест» (класс GUI), а затем применить его к моим конкретным типам? –

ответ

0

После выяснения некоторых вещей я могу ответить на свой вопрос. Как упоминал Борис Паук, я открываю новый поток каждый раз, когда читаю файл, поэтому он всегда возвращает первый объект, Player. Итак, чтобы исправить это, я изменил свой метод загрузки на пустоту вместо того, чтобы возвращать 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); 

вместо того, чтобы установить каждую отдельную переменную.

Смежные вопросы