web-dev-qa-db-ja.com

Java例外がキャッチされない

Javaでいくつかの例外がcatch (Exception ex)でキャッチされないのはなぜですか?これは、未処理の例外で完全に失敗するコードです(Javaバージョン1.4)。

public static void main(String[] args) {
    try {
        //Code ...
    } catch (Exception ex) {
        System.err.println("Caught Exception");
        ex.printStackTrace();
        exitCode = app.FAILURE_EXIT_CODE;
    }
    finally {
        app.shutdown();
    }
    System.exit(exitCode);
}

Exception in thread "main" Java.lang.NoSuchMethodError

しかし、これはうまくいきます

public static void main(String[] args) {
    int exitCode = app.SUCCESS_EXIT_CODE;
    try {
        //Code ...
    } catch (Java.lang.NoSuchMethodError mex){
        System.err.println("Caught NoSuchMethodError");
        mex.printStackTrace();
        exitCode = app.FAILURE_EXIT_CODE;
    } catch (Exception ex) {
        System.err.println("Caught Exception");
        ex.printStackTrace();
        exitCode = app.FAILURE_EXIT_CODE;
    }
    finally {
        app.shutdown();
    }
    System.exit(exitCode);
}

Caught NoSuchMethodError Java.lang.NoSuchMethodError:

例外をキャッチするとすべての例外をキャッチできると思いましたか? Javaですべての例外をキャッチするにはどうすればよいですか?

44
C. Ross

一部の例外はExceptionから派生していないためです。 ThrowableおよびError

基本的に、タイプ階層は次のとおりです。

       Object
         |
      Throwable
     /         \
Exception      Error

スローできるのはThrowablesと派生クラスのみなので、Throwableをキャッチすると、すべてがキャッチされます。

ThrowableException、およびExceptionから派生するすべての例外otherRuntimeExceptionから派生したもの以外はチェックされた例外としてカウントされます-それらは、スローするか、スローするものを呼び出す場合にキャッチすることを宣言する必要があるものです。

Java例外階層は少し混乱しています...

124
Jon Skeet

Error sではない Exception s。

クラスExceptionとそのサブクラスは、合理的なアプリケーションがキャッチする可能性のある条件を示すThrowableの形式です。

- JavaDoc for Java.lang.Exception

Errorは、Throwableのサブクラスであり、妥当なアプリケーションがキャッチしようとしてはならない重大な問題を示します。

- JavaDoc for Java.lang.Error

ThreadDeath など、特定のエラーをキャッチしたい場合があります。以下で説明するように、ThreadDeathはエラーとして分類されます。

ThreadDeathクラスは、「通常の発生」であっても、具体的にはExceptionではなくErrorのサブクラスです。これは、多くのアプリケーションがExceptionの発生をすべてキャッチしてから、例外を破棄するためです。

- ThreadDeathのJavaDoc

ただし、Threadのstop()メソッドは廃止されたため、使用しないでください。したがって、ThreadDeathが表示されることはありません。

6
Powerlord

例外はThrowableの一種にすぎません。 NoSuchMethodErrorは例外ではなくエラーです。これは別の種類のThrowableです。

4
Carl Manaster

Throwableをキャッチできます。エラーと例外はThrowableを拡張します。

throwable JavaDoc を参照してください:

Throwableクラスは、Java言語のすべてのエラーと例外のスーパークラスです。

3
akf

他のポスターが指摘しているように、すべてのスロー可能なオブジェクトがExceptionのサブクラスであるとは限りません。ただし、ほとんどの場合、ErrorまたはThrowableをキャッチすることはお勧めできません。これらの条件には、簡単に回復できない非常に深刻なエラー条件が含まれているためです。あなたの回復コードは物事を悪化させるだけかもしれません。

1
Simon Nickerson

最初に、この議論におけるいくつかの不幸な意味の混乱を明らかにしましょう。 Java.lang.Exceptionクラスがあり、これを単に大文字の「E」を使用した例外と呼ぶことができます。次に、言語機能である小文字の「e」を除いて例外があります。小文字バージョンはThrowableクラスの documentation で確認できます。

例外のコンパイル時チェックのために、Throwable、およびRuntimeExceptionまたはErrorのサブクラスではないThrowableのサブクラスは、チェックされた例外と見なされます。

私にとっては、この質問に対する答えを、チェック済みの例外とチェックなしの例外(小文字のe)として考える方が簡単です。チェックされた例外はコンパイル時に考慮する必要がありますが、チェックされていない例外は考慮されません。例外(大文字のE)とそのサブクラスはチェックされた例外です。つまり、コードによってスローされる可能性のある例外をキャッチするか、メソッドがスローできる例外をキャッチする必要があります(キャッチされない場合)。

エラーとそのサブクラスは未チェックの例外です。つまり、コードはスローされる可能性のあるエラーをキャッチする必要がなく、それらのエラーをスローすることを宣言する必要もありません。 RunTimeExceptionとそのサブクラスも、クラス階層内の場所に関係なく、チェックされない例外です。

次のコードを検討してください。

void test() {
  int a = 1, b = 0, c = a / b;
}

実行すると、上記のコードはJava.lang.ArithmeticExceptionを生成します。これは、例外がスローされ、コードがArithmeticExceptionをキャッチしたり、この例外をスローすることを宣言したりしていなくても、エラーなしでコンパイルされます。これは、チェックされていない例外の本質です。

クラス階層内のArithmeticExceptionの場所を考慮してください。特に、これがJava.lang.Exceptionのサブクラスであるという事実を考慮してください。ここには、Java.lang.Exceptionから派生した例外がありますが、これはJava.lang.RuntimeExceptionのサブクラスでもあるため、チェックされていない例外なので、キャッチする必要はありません。

Java.lang.Object
  Java.lang.Throwable
    Java.lang.Exception
      Java.lang.RuntimeException
        Java.lang.ArithmeticException

スローされる可能性のあるものをキャッチしたい場合は、Throwableをキャッチしてください。ただし、これらのThrowableの一部は、キャッチされるべきではない致命的な実行時の状態になる可能性があるため、これは最も安全な方法ではない可能性があります。または、Throwableをキャッチした場合、処理できないThrowableを再スローすることもできます。状況によります。

0
Danger

他の両方の投稿が指摘しているように、catch(Exception e)は Exception から派生する例外に対してのみ機能します。ただし、ツリー階層を見ると、 Throwable の場合は例外であることがわかります。 Throwableは Error の基本クラスでもあります。したがって、NoSuchMethodErrorの場合、それはエラーであり、例外ではありません。 * IOと* Exceptionの命名規則(IOExceptionなど)に注意してください。

0
JasCav