ネットワークを使用する Java ゲームがあり、(Socket を使用して) クライアントが 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);
}
「app」は、受信したすべての新しいオブジェクトを処理して処理するインスタンスです。
アプリ ( 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);
}
}
このコードをデバッガーで 1 ステップずつ実行したところ、完全に動作しました。ただし、通常どおり実行すると、null ポインターが返されます (出力は次のとおりです:)
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)
ここで、オブジェクトが 2 回印刷されているのがわかるので、受信したことはわかりますが、null ポインターが返されます。
関数の途中にスリープ関数を追加しました。
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);
}
そして、しばらくスリープ状態にすると、ようやくすべてが機能しました。
このようにスレッドをスリープ状態にする必要がある理由は何ですか? 何か違うことをしなければならないことはありますか?オブジェクトがまだnullと見なされているときにオブジェクトを印刷できた理由がわかりません。
編集:さらにコンテキストを追加しました。