2013-08-08 4 views
22

tryブロックにreturn;が存在する場合、try-finally実行について混乱します。私の理解では、finallyブロックは常に実行されます。つまり、呼び出し元のメソッドに戻る前に実行されます。java:finallyブロックの実行を試みてください

public class TryCatchTest { 
    public static void main(String[] args){ 
     System.out.println(test()); 
    } 
    static int test(){ 
     int x = 1; 
     try{ 
      return x; 
     } 
     finally{ 
      x = x + 1; 
     } 
    } 
} 

結果は実際には1です。これはfinallyブロックが実行されていないことを意味しますか?誰もそれで私を助けることができますか?

+1

なぜ、 'System.out.println()'をfinallyブロックに追加して自分自身を見ていないのですか?私はそれが実行されると思うが、返される値は1です。 –

+0

try catchを使用すると、特定のタイプの例外(例:IOException、NullPointerExceptionなど)をcatchできます。とにかくキャッチの前にいくつかのコードを実行してください。 – RicardoE

+7

[こちらは] upvoting中に考えることについて何か – keyser

答えて

23

ブロックtryから戻ると、戻り値はそのメソッドのスタックフレームに格納されます。その後、finallyブロックが実行されます。

finallyブロックの値を変更しても、すでにスタック上の値は変更されません。しかし、finallyブロックから再び戻ると、スタックの戻り値が上書きされ、新しいxが返されます。

最終的にブロックにxの値を印刷すると、実行されたことがわかり、xの値が印刷されます。

static int test(){ 
    int x = 1; 
    try{ 
     return x; 
    } 
    finally{ 
     x = x + 1; 
     System.out.println(x); // Prints new value of x 
    } 
} 

注:基準値の場合には、基準の値がスタックに格納され、返されます。その場合、その参照を使用してobjectの値を変更することができます。

StringBuilder builder = new StringBuilder(""); 
try { 
    builder.append("Rohit "); 
    return builder; 

} finally { 
    // Here you are changing the object pointed to by the reference 
    builder.append("Jain"); // Return value will be `Rohit Jain` 

    // However this will not nullify the return value. 
    // The value returned will still be `Rohit Jain` 
    builder = null; 
} 

読む推奨:

+0

ダング、私にそれを打つ! –

+7

これに追加:スタックには、戻り値*自体だけが格納されます。オブジェクトへの参照を返す場合、 'finally'ブロックで行われたオブジェクトのフィールドへの変更は引き続き表示されます。 –

+0

@JasonC。うん、本当。答えに追加されます。ありがとう:) –

10

finallyブロックが実行されます。ローカル変数がインクリメントされます。しかし、そのローカル変数の値はすでに戻り値としてコピーされています。 Java言語仕様、14.17: The return statementから

:式と

return文は、それを含むメソッドの呼び出し に制御を移すしようとします。式の値はメソッド呼び出しの の値になります。任意のブロックを試すか、メソッドまたはコンストラクタ 内の文(§14.20)がしようとしている場合ので

...

前の記述が言うには、だけでなく、「転送 制御」「コントロールを転送しようとします」 catch節にreturn文が含まれていれば、最後に のtry文が実行されます。 コントロールがメソッドまたはコンストラクタの呼び出し側に転送される前に、最も内側から最外側に順番に実行されます。 finally節の中途完了は、あなたが試す終了する前にXを返却するreturn文

+3

まあ、私は*誰かが実際にドキュメントを読む必要があったと思います。すべての当事者はプーパを持っています。 –

0

によって開始された制御の移動を中止することができます。私はこれを行うでしょう:

public class TryCatchTest { 
    public static void main(String[] args) { 
     System.out.println(test()); 
    } 
    static int test() { 
     int x = 1; 
     try { 
      do something with x. 
     } finally { 
      do something that will happen even in case of error; 
      x = x + 1; 
      return x; 
     } 
    } 
} 
+1

私はその点を逃すと思います。 –

関連する問題