try-finallyとtry-catchの違い


90

違いは何ですか

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

そして

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

Throwableにアクセスできるので、2番目のバージョンの方が好きです。2つのバリエーションの間に論理的な違いや推奨される慣習はありますか?

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

回答:


121

これらは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
    }
}

11
当然の結果では、ということであることはできないアクセスThrowableからfinally存在していない可能性があるため、ブロックすることThrowable
ディーンハーディング、

11

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


7

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

  • 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つ以上のcatchブロックと1つのfinallyブロック

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

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
}

4

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
}

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ブロックが実行されます。

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


3

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

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


2

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


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();
           }
       }
    }

}

たぶん私のような他の人がこのようなものを検索しました。

このページからの情報tutpoint


1

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


1

最初の形式でも、呼び出しメソッドに記録できます。そのため、特別な処理をここで行いたくない限り、大きな利点はありません。


0

Tryブロックは、例外を発生させるステートメントを保持します。catchブロックは、tryブロックからスローされた参照を保持し、必要なメッセージがcatchブロックから生成されます。最後に、ブロックは、ioクローズ、ファイルクローズ、dBクローズなどの使用済みリソースをクローズするためにも使用されます。Java-9では、tryの外側でリソースが宣言されている拡張try-withリソースが登場しました。必須です

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.