74

上記のトピック (タイトルを参照) に関連して、このフォーラムで既に尋ねられたすべての質問を読むことで、finallyが常に呼び出されることを完全に理解しています。System.exit(fromおよび無限ループを除く)。returnただし、 catch ブロックで a が呼び出されてreturnから、finally ブロックから別のa が呼び出されるかどうかを知りたいです。

例えば:

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 句 return によって既に書き込まれている内容を最終的に上書きするという事実を見つけました。私の理解では、catch 句の戻り値が評価されようとするとすぐに、制御フローが finally 句に渡され、次に別の戻り値が返されます。今回は、制御を catch 句に戻さずに戻り値が評価されます。 . このようにしてreturn、実行時に呼び出されるのは最終的に返されるだけです。それに同意しますか?

returninfinallyは制御をプログラムに戻しませんが、値を返し、メソッドを終了します。そう言えますか?

4

2 に答える 2

114

returnブロック内のにtry到達すると、制御がfinallyブロックに転送され、関数は最終的に (スローではなく) 通常どおりに戻ります。

例外が発生しても、コードがブロックreturnからa に到達した場合catch、制御はブロックに転送されfinally、関数は最終的に正常に戻ります (スローではありません)。

あなたの例では、 に があるreturnため、finally何が起こっても、関数は を返します。34finally

あなたの例ではカバーされていませんが、ブロックcatchに例外がスローされ、キャッチされなかった場合でも、これは当てはまります。ブロックからaを実行することで、例外を完全に抑制します。検討:tryreturnfinally

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 最後に戻る

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

returnこれが、 inの使用を避けることが最善である理由の 1 つfinallyです。

于 2013-03-05T14:11:24.040 に答える
84

これがどのように機能するかを示すいくつかのコードです。

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
于 2013-03-05T14:18:20.370 に答える