8

私は次の例について考えます。しかし、finallyブロックの重要性を理解できませんでした。これら2つのコードサンプルの実行の違いを教えてください。また、実際の例も役立ちます。

サンプル1:

    try{
       // some code 1
    }catch(Exception ex){
       // print exception   
    }finally{
       // some code 2            
    }

サンプル2:

    try{
      // some code 1
    }catch(Exception ex){
      // print exception   
    }
    // some code 2
4

7 に答える 7

17

提示した2つのスニペットには大きな違いがあります。たとえば、catchブロック自体が例外をスローした場合finallyでも、ブロックはそのセマンティクスによって実行されます。

これは次のスニペットの印刷ですが、そうではあり"Finally!"ません"What about me???"

    try {
        throw null;     // throws NullPointerException!
    } catch (Exception e) {
        int oops = 1/0; // throws ArithmeticException!
    } finally {
        System.out.println("Finally!"); // still gets executed!
    }
    System.out.println("What about me???"); // doesn't get executed!

一般的に言えば、ブロックのfinallytry実際には常に実行されます。tryブロックに続くコードには、そのような保証はありません。


しかし、私のcatchブロックが単なるprintステートメントである場合はどうなりますか?

それが何かをしないという保証はまだありませんthrow。例外の詳細メッセージの作成など、まだ問題が発生する可能性があります。

catchコードが「安全」であり、ステートメントに続くコードが常に実行されることを保証するために最善を尽くしてもtry、質問は「なぜ?」になります。なぜ回避するfinallyのに、そのセマンティクスを複製するために一生懸命努力するのですか?

finallyセマンティクスは保証されており、コードの作成者または作成者からの立証責任は必要ありません。このため、ブロックを使用して必須の「クリーンアップ」コードを配置するのは慣用的です。finallyを使用finallyすると、正確性が保証され、書き込み可能性と可読性の両方が向上します。

于 2010-06-30T08:56:12.720 に答える
8

たとえば、例でブロックにキャッチされていないがスローfinallyされた場合でも、ブロックは実行されます。したがって、ブロックにクリーンアップコードを配置できます。これは、およびブロックでの操作の結果に関係なく、常に実行する必要があります。Errorcatchfinallytrycatch

通常、catchブロックはより具体的なタイプの例外(多くの場合、チェックされた例外のみ)をキャッチするため、ほとんどの場合、上記の2つのコード例の違いは非常に明確です。

更新:catchブロックが例外をスローすることは決してないので、必要ないと言うかもしれfinallyません。ただし、次の2つの点に注意してください。

  • これはコードの現在の状態にすぎず、将来変更される可能性があります-例外をスローする可能性のあるコードをブロックに追加する将来のプログラマーがcatch、クリーンアップコードをブロックに入れることを忘れないでfinallyください。
  • try-catch-finallyは、コードを読んでいる人々が何が起こっているのかを理解しやすくするプログラミングイディオムです。一般的なイディオムを使用しないと、誤解を招く恐れがあり、長期的にはバグが発生します。
于 2010-06-30T08:53:55.047 に答える
2

このブロックを使用してfinally、例外がスローされた(およびキャッチされた)かどうかに関係なく実行する必要のあるコードをクリーンアップして実行します。catchこれには、ブロック内にあるコードが含まれます。

于 2010-06-30T08:53:30.490 に答える
1

tryブロックで使用したリソースを解放したい場合に役立ちます。したがって、どのような場合でも見逃さずにそれらを実行する唯一の場所は、最終的にブロックです。例外がスローされた場合、javaはその直後のコードを実行しないためです。キャッチブロックに直接ジャンプします。

于 2010-06-30T08:58:24.520 に答える
0

実際には、finallyブロックは、例外が発生した場合でも、開いているリソースを閉じるために使用されます。たとえば、ファイルを読み取る(または書き込む)とき、データベースにアクセスするときなどです。

public void readFile(String fileName) {
    FileReader fr;
    BufferedFileReader bfr;

    try {
        fr = new FileReader(fileName);
        bfr = new BufferedFileReader(fr);
        // ...
    } catch (IOException ioe) {
        // ...
    } finally {
        // TO ENSURE THAT THE READERS ARE CLOSED IN ALL CASES
        if (bfr != null) { 
            try {
                bfr.close();
            } catch (IOException ignoredIOE) {}
        }
        if (fr != null) { 
            try {
                fr.close();
            } catch (IOException ignoredIOE) {}
        }
    }
}
于 2010-06-30T10:30:37.333 に答える
0

最後にキャッチなしで試してみることができることに注意してください:

try{
   // some code 
}finally{
   // cleanup code
}

したがって、例としては、呼び出し元に例外を伝播したいが、ルックを解放するなどのクリーンアップコードが必要なメソッドがあります。

于 2010-06-30T09:00:13.813 に答える
0

tryブロックのステートメントがチェックされていない例外をスローした場合、finallyブロックが実行され、プログラマーが関連するアクションを実行できるようになります。

于 2010-06-30T09:08:22.670 に答える