100

違いは何ですか

try {
    fooBar();
} finally {
    barFoo();
}

try {
  fooBar();
} catch(Throwable throwable) {
    barFoo(throwable); // Does something with throwable, logs it, or handles it.
}

2 番目のバージョンの方が、Throwable にアクセスできるので気に入っています。2 つのバリエーションの間に論理的な違いや好ましい規則はありますか?

また、finally 節から例外にアクセスする方法はありますか?

4

11 に答える 11

131

これらは 2 つの異なるものです。

  • catch ブロックは、try ブロックで例外がスローされた場合にのみ実行されます。
  • 例外がスローされたかどうかにかかわらず、finally ブロックは常に try(-catch) ブロックの後に実行されます。

あなたの例では、3番目の可能な構成を示していません:

try {
    // try to execute this statements...
}
catch( SpecificException e ) {
    // if a specific exception was thrown, handle it here
}
// ... more catches for specific exceptions can come here
catch( Exception e ) {
    // if a more general exception was thrown, handle it here
}
finally {
    // here you can clean things up afterwards
}

そして、@codeca がコメントで述べているように、finally ブロックは例外がなくても実行されるため、finally ブロック内の例外にアクセスする方法はありません。

もちろん、ブロック外で例外を保持する変数を宣言し、catch ブロック内で値を代入することもできます。その後、finally ブロック内でこの変数にアクセスできます。

Throwable throwable = null;
try {
    // do some stuff
}
catch( Throwable e ) {
    throwable = e;
}
finally {
    if( throwable != null ) {
        // handle it
    }
}
于 2010-05-18T06:17:05.667 に答える
14

これらはバリエーションではなく、根本的に異なるものです。 例外が発生した場合にのみ、常にfinally実行されます。catch

于 2010-05-18T06:17:49.910 に答える
7

最後に、catchブロックはまったく異なります。

  • catchブロック内で、スローされた例外に応答できます。このブロックは、未処理の例外があり、タイプが1つと一致するか、catchブロックのパラメーターで指定されたもののサブクラスである場合にのみ実行されます。
  • 最後に、例外が発生したかどうかに関係なく、tryおよびcatchブロックの後に常に実行されます。

それで

try {
  //some code
}
catch (ExceptionA) {
  // Only gets executed if ExceptionA 
  // was thrown in try block
}
catch (ExceptionB) {
  // Only executed if ExceptionB was thrown in try 
  // and not handled by first catch block
}

とは異なり

try {
  //some code
}
finally {
  // Gets executed whether or not 
  // an exception was thrown in try block
}

大幅。

tryブロックを定義する場合は、定義する必要があります

  1. 最後にブロックするか、
  2. 1つ以上のキャッチブロック、または
  3. 1つ以上のキャッチブロックと1つの最終ブロック

したがって、次のコードも有効です。

try {
  //some code
}
catch (ExceptionA) {
  // Only gets executed if 
  // ExceptionA was thrown in try block
}
catch (ExceptionB) {
  // Only executed if ExceptionB was thrown in 
  // try and not handled by first catch block
}
//even more catch blocks
finally {
  // Gets executed whether or not an 
  // exception was thrown in try block
}
于 2010-05-18T15:12:13.427 に答える
5

try例外をスローする可能性のあるメソッドを実行するために使用されます

catchその例外を「キャッチ」して停止するために使用されます

finallyその例外がキャッチされたかどうかにかかわらず、必要なクリーンアップに使用されます

try{
    myObject.riskyMethod(); // run a method that may throw an exception
}
catch(Exception ex){
    myLogger.log(ex.Message); // "catch" stop that exception
}
finally{
    myObject = null; // clean up needed from that exception being caught
}
于 2010-05-18T06:17:43.250 に答える
3

最後に、catch ブロックはかなり異なります。

catch ブロック内で、スローされた例外に応答できます。このブロックは、未処理の例外があり、型が catch ブロックのパラメーターで指定された型と一致するか、そのサブクラスである場合にのみ実行されます。finally は、例外が発生したかどうかにかかわらず、常に try および catch ブロックの後に実行されます。

于 2016-02-11T16:01:57.893 に答える
3
try {
    statements;
} catch (exceptionType1 e1) {      // one or multiple
    statements;                 
} catch (exceptionType2 e2) {
    statements;
}    
...
} finally {                                 // one or none
    statements;
}
  1. すべての try ステートメントには、1 つの catch 句または finally 句のいずれかを含める必要があります
  2. 複数の catch 句を持つことができますが、finally 句は 1 つだけです
  3. 実行中にエラーが発生した場合、コントロールは適切な Catch ブロックに転送され、ステートメントが実行され、Finally ブロックが実行されます。

何があっても、Finally ブロックは常に実行されます。したがって、一般的に、Finally ブロックが使用されます。セッション、データベース接続、またはファイルまたはソケットが開いている場合、それらの接続を閉じるためのコードが配置されます。これは、アプリケーションでメモリ リークやその他の問題が発生しないようにするためのものです。

于 2010-05-18T07:08:21.563 に答える
2

通常、ストリームや接続などのリソースを使用するときは、finally ブロックを使用して明示的に閉じる必要があります。以下のプログラムでは、FileReader を使用してファイルからデータを読み取り、finally ブロックを使用してファイルを閉じています。

import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class ReadData_Demo {

   public static void main(String args[]){
      FileReader fr=null;       
      try{
         File file=new File("file.txt");
         fr = new FileReader(file);  char [] a = new char[50];
         fr.read(a); // reads the content to the array
         for(char c : a)
         System.out.print(c); //prints the characters one by one
      }catch(IOException e){
          e.printStackTrace();
       }
       finally{ 
          try{
              fr.close();
          }catch(IOException ex){       
               ex.printStackTrace();
           }
       }
    }

}

多分私のような他の人はこのようなものを探しました.

このページの情報

于 2016-09-12T08:32:38.107 に答える
2

私の研究では、Finally ブロックは常に実行され、主に「開いている接続を閉じるために使用」され、不必要に実行されているものを破棄します。

于 2015-10-14T08:26:24.377 に答える
1

最初のフォームでも、呼び出し元のメソッドに記録できます。そのため、特別な処理をすぐに行いたい場合を除き、大きな利点はありません。

于 2010-08-27T02:36:53.840 に答える
1

最後にブロックは常に実行されます。Catch ブロックは、blocks パラメーターに一致する例外がキャッチされた場合にのみ実行されます。

于 2010-05-18T06:18:11.103 に答える