11

このコードを試してください。getValueB() が 2 ではなく 1 を返すのはなぜですか? 結局のところ、increment() 関数が 2 回呼び出されています。

    public class ReturningFromFinally
    {
      public static int getValueA() // This returns 2 as expected
      {
         try     { return 1; }
         finally { return 2; }
      }

      public static int getValueB() // I expect this to return 2, but it returns 1
      {
        try     { return increment(); }
        finally { increment(); }
      }

      static int counter = 0;

      static int increment()
       {
          counter ++;
          return counter;
       }

      public static void main(String[] args)
      {
          System.out.println(getValueA()); // prints 2 as expected
          System.out.println(getValueB()); // why does it print 1?
      }
}
4

6 に答える 6

18

結局のところ、increment() 関数が 2 回呼び出されています。

はい。ただし、戻り値は2 回目の呼び出しの前に決定されます。

返される値は、「実行がメソッドを終了する直前」ではなく、その時点での return ステートメントの式の評価によって決定されます。

JLS のセクション 14.17から:

Expression を含む return ステートメントは、それを含むメソッドの呼び出し元に制御を移そうとします。Expression の値がメソッド呼び出しの値になります。より正確には、そのような return ステートメントの実行は、最初に Expression を評価します。Expression の評価が何らかの理由で突然終了した場合、return ステートメントはその理由で突然終了します。Expression の評価が正常に完了して値 V が生成された場合、return ステートメントは突然完了します。その理由は、値 V で返されるためです。

次に、JLS のセクション 14.20.2 に従って、実行がfinallyブロックに転送されます。ただし、return ステートメントの式は再評価されません。

最終ブロックが次の場合:

finally { return increment(); }

その新しい戻り値は、メソッドの最終的な結果になります (セクション 14.20.2 に従って) - しかし、あなたはそうしていません。

于 2012-08-15T21:33:41.993 に答える
5

私のコメントを参照してください。

2あなたが持っていれば、それは戻ってきますfinally { return increment(); }。最初のreturnステートメントの式は、finally ブロックの前に評価されます。JLS のセクション 14.20.2 を参照してください。

ブロックの実行がtry正常に完了すると、finallyブロックが実行され、次の選択肢があります。

  • finallyブロックが正常に完了すると、ステートメントtryは正常に完了します。
  • finallyブロックが理由で突然完了する場合Stry文は理由で突然完了しSます。

getValue2(現在のように)2回呼び出すと、1その後に3.

于 2012-08-15T21:35:04.293 に答える
0

メソッドのfinallyブロックはGetValue2何も返しません。インクリメントするメソッドを呼び出しているだけcounterです。

于 2012-08-15T21:33:46.277 に答える
0

getValue2() メソッドでは、最終的にブロックが increment() を呼び出すだけなので、それは返されません。したがって、コードが行っていることは、インクリメントしてカウンター (1) を返し、次にカウンターを 2 にインクリメントしますが、それを返しません。

于 2012-08-15T21:34:22.360 に答える
0

2 番目の例では、明示的な戻り値はありません。この場合、tryブロック内の値を返します。ブロックJava内のコードが既に実行されているため、直感的に理解できます。tryブロックを実行した後、そのブロックを再度実行することはありませんfinally

于 2012-08-27T05:06:07.247 に答える