У меня есть игра Java, в которой используется сеть, и у меня есть клиент (использующий сокет), извлекающий объекты из ObjectInputStream, работающий в своем собственном потоке.
С Client.java :
Object input = null;
while(true) {
input = in.readObject();
if(input != null) {
listener.gotObject(input);
}
}
Это работает довольно хорошо. Объект получен и передан слушателю, который является классом, связанным с моим основным классом GameApp.
От слушателя ( NetControl.java ):
public void gotObject(Object o) {
System.out.println(o);
app.gotObject(o);
}
«приложение» - это экземпляр, который обрабатывает все новые полученные объекты и обрабатывает их.
Из приложения ( GameApp.java ) ( редактировать: неабстрактный CardGameApp.java дает больший контекст ):
public void gotObject(Object o) {
// select instance:
if(o instanceof GameList) {
GameList gameList = (GameList) o;
System.out.println("gamelist: " + gameList);
this.lobbyControl.gotGameList(gameList);
}
}
Я запускал этот код в отладчике по одному шагу за раз, и он отлично работает. Когда я запускаю его как обычно, я получаю нулевой указатель (вывод выглядит следующим образом:)
Game ID: 0. Name: game1. Players: 1 / 1. // the object, as it is printed in Client.java
gamelist: Game ID: 0. Name: game1. Players: 1 / 1. // the object, as it is printed again in GameApp.java
Exception in thread "Thread-1" java.lang.NullPointerException
at com.lgposse.game.app.GameApp.gotObject(GameApp.java:61)
at com.lgposse.game.net.NetControl.gotObject(NetControl.java:47)
at com.lgposse.net.client.Client.run(Client.java:49)
Теперь я вижу, что объект печатается дважды, поэтому я знаю, что он был получен ... но я получаю нулевой указатель.
Я добавил функцию сна в середине функции:
else if(o instanceof GameList) {
GameList gameList = (GameList) o;
System.out.println("gamelist: " + gameList);
try {
Thread.sleep(1000); // sleep 100 still gave null pointer
} catch (InterruptedException e) {}
this.lobbyControl.gotGameList(gameList);
}
И, поспав некоторое время, все наконец заработало.
Любая идея, почему мне нужно спать нить, как это? Есть ли что-то, что я должен сделать по-другому? Я не уверен, почему мне удалось напечатать объект, пока он все еще считался нулевым.
Редактировать: добавлен дополнительный контекст.