6

私はこのコードを実行します:

public class User {

    public static void main(String args[]) {
        int array[] = new int[10];
        int i = 1;
        try {
            System.out.println("try: " + i++);
            System.out.println(array[10]);
            System.out.println("try");
        } catch (Exception e) {
            System.out.println("catch: " + i++);
            System.out.println(array[10]);
            System.out.println("catch");
        } finally {
            System.out.println("finally: " + i++);
            Object o = null;
            o.hashCode();
            System.out.println("finally");
        }

    }
}

結果:
try:1
catch:2
finally:3
スレッド"main"の例外java.lang.NullPointerExceptionat user.main(User.java:17)

ブロックキャッチ内-ArrayIndexOutOfBoundsExceptionですが、この例外が失われるのはなぜですか?

4

3 に答える 3

7

JLSから

これについては、JLSの「ブロックとステートメント」のセクション「14.19.2try-catch-finallyの実行」で読むことができます。そして私は引用します、

他の理由Rでtryブロックの実行が突然完了した場合、finallyブロックが実行されます。次に、選択肢があります。
  • finallyブロックが正常に完了すると、理由Rのためにtryステートメントが突然完了します。
  • 理由Sのためにfinallyブロックが突然完了した場合、理由Sのためにtryステートメントが突然完了します(理由Rは破棄されます)。例...

したがって、以下(質問者のコードから実際に凝縮されたもの)は、ExceptionTestスローされたものではなく、NPEで完了します。

class Phinally
{
  static class ExceptionTest extends Exception
  { public ExceptionTest(String message) { super(message); }  }

  public static void main(String[] args) throws ExceptionTest
  {
    try {
      System.out.println("Foo.");
      throw new ExceptionTest("throw from try"); 
    } finally {
      throw new NullPointerException("throw from finally");
    }    
  }
}

tryリソース/ARMブロックに関するサイドバー

try特にリソースの管理、ネストされた//ブロック、catchおよびfinallyネストされた内部ブロックを必要とするいくつかの一般的なケースでこれについて推論することの難しさfinallyは、プロジェクトCOIN(Javaにかなり早く統合される)の「リソースで試す」機能の理由の一部です。 ")、これについてはここで詳細を読むことができます。

これは、 PMDのような静的アナライザーの実行に時間を費やす多くの理由の1つです。これは、このタイプの混乱を見つけて不平を言います。コードでケースをキャッチできない場合もありますが、よくわかりません。

静的チェック

@stacktraceからのコメントのフォローアップ:PMDとFindBugsを介して関連するコードを実行し、次の両方を試しました。

finally { throw NullPointerException("Foo"); }

finally { Object o = null; System.out.println(o.toString()); }

finally前者の場合、PMDは、条項から例外がスローされることに気づき、不満を述べました。FindBugsはまったく文句を言いません。後者の場合、PMDはいくつかのことについて不平を言いましたが、関連するものは何もありません( "LocalVariableCouldBeFinal"、 "StringToString"、および "UselessOperationOnImmutable")。しかし、FindBugsはnullの逆参照に気づき、不満を漏らしました。この話の教訓?PMDとFindBugsの両方を実行してください!

関連している

SOに関連:catch/finallyでスローされた嚥下例外そのような面倒な試行/キャッチ/最終的に回避できますか...

于 2010-10-17T19:01:24.427 に答える
3

あなたはJavaの奇妙な機能に出くわしました。それは、finallyブロックが適切に終了しない場合、以前にスローされた例外を非表示にするというものです。

これは仕様によるものであり、間違いではありません。

于 2010-10-17T18:36:52.710 に答える
1

最後の例外はtry { } catch { }ブロック内では発生しないためcatch { }finally { }処理はありません。

于 2010-10-17T18:37:30.907 に答える