2013-03-05 11 views
44

上記のトピック(タイトルを参照)に関連するこのフォーラムですでに質問されているすべての質問を読んで、finallyが常に呼び出されることを徹底的に理解します。 (System.exitと無限ループを除く)。しかし、returnがキャッチブロックで呼び出され、次にreturnがfinallyブロックから呼び出されたかどうかを知りたいと思います。例えばtry-catch-finally-return clarification

public static void main(String[]args) { 
    int a = new TestClass().absorbeTheValue(); 
} 

int absorbeTheValue() { 
    try { 
     int a = 10/0; 
     if (a > 0) return 4; 
    } catch(Exception e) { 
     return 45; 
    } finally { 
     return 34; 
    } 
}  

だからここで(メソッドが呼び出される)出力は、いずれの場合に34になるだろう。それは最終的に常に実行されることを意味します。他の「返品」は一切実行されていませんが、私は思っています。多くの記事で、私は最後に、catch節の復帰によって既に書かれた内容を上書きするという事実を発見しました。私の理解では、catch節の戻り値が評価されるとすぐに、制御フローはfinally節に渡され、今度は別の戻り値を返します。今回は、制御をcatch節に戻さずに戻り値が評価されます。このように、実行時に呼び出されるのはreturnだけです。それに同意しますか?

は、コントロールをプログラムに戻しませんが、値を返して終了します。私達はそう言うことができますか?

+4

インデントあなたのコードください。 –

+0

も参照してください:http://stackoverflow.com/questions/65035/in-java-does-return-trump-finally –

+0

あなたの質問は何ですか? – thiagoh

答えて

77

tryブロック内のreturnに到達すると、ブロックはfinallyブロックに制御を移し、最終的に機能は正常に戻ります(スローではありません)。

catchブロックからコードがreturnに達すると、ブロックはブロックに転送され、最終的に関数はスローされずに正常に戻ります。あなたの例では

、あなたはfinallyreturnを持っている、とfinallyは(あなたがする場合)、最終的な単語を持っているので、それほど関係なく、何が起こるかの、機能は、34を返します。

はあなたの例ではカバーされていないが、これはあなたがcatchを持っていなかったと例外がtryブロックでスローとがキャッチされなかった場合でも、場合にtrueになります。 finallyブロックからreturnを実行すると、例外が完全に抑制されます。考えてみましょう:

public class FinallyReturn { 
    public static final void main(String[] args) { 
    System.out.println(foo(args)); 
    } 

    private static int foo(String[] args) { 
    try { 
     int n = Integer.parseInt(args[0]); 
     return n; 
    } 
    finally { 
     return 42; 
    } 
    } 
} 

あなたが任意の引数を指定せずにいることを実行した場合:

$ java FinallyReturn

... fooのコードはArrayIndexOutOfBoundsExceptionをスローします。しかし、finallyブロックがreturnを実行するため、その例外は抑制されます。

これは、finallyreturnを使用しないようにする理由の1つです。

+0

'throw 'はこれらの目的のために' return'と互換性があることに注意することが重要です。 (例えば、「新しい例外を投げる(4)」、「新しい例外を投げる(34)」) – Marcus

+0

私はちょうどuser1442960が言ったものをチップに入れたいと思う。 JLSはキャッチやリターンについて何も言いません。それは私が推測している "突然"という言葉を、例外またはリターンのいずれかを意味します。 – Steve11235

+1

@ Steve11235:いいえ、 'catch'ブロックからの' return'は、 "突然"ではなく "通常"完了するでしょう。これは、[Section 11](http://docs.oracle.com/javase/specs/jls/se8/html/jls-11.html)から合理的にはっきりしています。*「例外をスローする処理中に、Java Virtualマシンは、現在のスレッドでは実行が開始されたが完了していない式、ステートメント、メソッド、コンストラクタ呼び出し、イニシャライザ、フィールド初期化式を1つずつ突然完了させます。 "* –

53

どのように動作するかを示すコードです。

class Test 
{ 
    public static void main(String args[]) 
    { 
     System.out.println(Test.test()); 
    } 

    public static String test() 
    { 
     try { 
      System.out.println("try"); 
      throw new Exception(); 
     } catch(Exception e) { 
      System.out.println("catch"); 
      return "return"; 
     } finally { 
      System.out.println("finally"); 
      return "return in finally"; 
     } 
    } 
} 

結果は次のとおりです。

try 
catch 
finally 
return in finally 
+3

+1わかりやすく、 ) – Logan

+1

@LoganDam TJ Crowderはとても良い説明をしてくれます。 – andre

+0

@LoganDam:操作の順番をきれいに説明できます。しかし、質問されている質問には答えません。質問は、 'finally'ブロックに' return'ステートメントが含まれているときに何が起こるかを明示的に尋ねます。 – unholysampler

関連する問題