1

例外の一般的なルールは、一般的なものをキャッチする前に、より具体的なものをキャッチすることです。SocketException: socket closedサーバーを閉じると、によってキャッチされるリスナーからスローがスローされる場合がありますがIOException、サーバーを閉じるときにそのメッセージをユーザーに表示したくありません。他のすべてはおそらく実際のエラーなので、それらに表示する必要があるため、 をキャッチしSocketException、そのメッセージを確認し、そうでない場合は、キャッチsocket closedして として処理するために再スローする必要がありIOExceptionます。Java/NetBeans 7.0.1 はそれを好まないようです。これが私のコードです:

public void run() {
        while (runner == Thread.currentThread()) {
            System.out.println("waiting for connection...");
            try {
                Socket s = server.accept(); //throws SocketException/IOException
                if (session == null) {
                    session = new ReceiveSession(s, parent);
                } else {
                    s.close();
                }
            } catch (SocketException e) {
                if (!e.getMessage().equals("socket closed")) {
                    throw e; //error line, "unreported exception SocketException"
                }
            } catch (IOException e) {
                e.printStackTrace();
                parent.showError("Someone tried to connect but the connection failed: " + e);
                session = null;
            }
        }

    }

クリーンアップしてビルドしようとすると、次のようになります。

error: unreported exception SocketException; must be caught or declared to be thrown
                throw e;
1 error

SocketExceptionextendsであるためIOException、より一般的なIOException. なぜこのエラーが発生するのですか? (プロジェクトをそのまま NetBeans で実行すると完全に機能しますが、サーバーが必要に応じてシャットダウンしたときに例外がユーザーに表示されることはありません。)

4

3 に答える 3

6

あなたthrowはブロックの外側にあるtryため、スローされた例外は以下では処理されませんcatch

于 2013-01-04T09:58:19.447 に答える
4

try2 番目のcatch は、2 番目の catch が担当するブロックでスローされなかったので、rethrow をキャッチしません。コードを再構築する必要があります。


たとえば、最も単純な再構築は次のようになります。

public void run() {
    while (runner == Thread.currentThread()) {
        System.out.println("waiting for connection...");
        try {
            try {
                Socket s = server.accept(); //throws SocketException/IOException
                if (session == null) {
                    session = new ReceiveSession(s, parent);
                } else {
                    s.close();
                }
            } catch (SocketException e) {
                if (!e.getMessage().equals("socket closed")) {
                    throw e; //error line, "unreported exception SocketException"
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
            parent.showError("Someone tried to connect but the connection failed: " + e);
            session = null;
        }
    }
}

ネストされた試行は少し泣かせますが、それは仕事を終わらせるでしょう (そして正直に言うと、頭のてっぺんから離れて、行き過ぎないより良い方法は考えられません)。

于 2013-01-04T09:58:20.727 に答える
0

Catch ステートメントは、リスト内の他の catch ブロックからではなく、それぞれの try ブロックから例外をキャッチします。try の外側から例外をスローしているため、後続の catch ブロックによってキャッチされません。

于 2013-01-04T10:02:54.163 に答える