声明では:
fooFunc().barFunc(bazFunc());
barFunc()bazFunc()両方がfooFunc()完了するまで実行できないことは明らかです。
しかし、 と の実行順序はfooFunc()保証bazFunc()されていますか?
関連する (しかし異なる!) 質問: Java でのパラメーターの実行順序は保証されていますか?
声明では:
fooFunc().barFunc(bazFunc());
barFunc()bazFunc()両方がfooFunc()完了するまで実行できないことは明らかです。
しかし、 と の実行順序はfooFunc()保証bazFunc()されていますか?
関連する (しかし異なる!) 質問: Java でのパラメーターの実行順序は保証されていますか?
このためのドキュメントは15.12.4です。メソッド呼び出しの実行時評価
「実行時に、メソッド呼び出しには5つのステップが必要です。最初に、ターゲット参照を計算できます。次に、引数式が評価されます。3番目に、呼び出されるメソッドのアクセシビリティがチェックされます。4番目に、実行するメソッドが特定されます。第5に、新しいアクティベーションフレームが作成され、必要に応じて同期が実行され、制御がメソッドコードに移されます。」
この例でfooFunc()は、はターゲット参照の計算の一部として呼び出されbazFunc()、引数式の1つであるため、fooFunc()最初に呼び出す必要があります。
JLS、Java SE 7 Editionには次の例があり、それはfooFunc()以前のものであると言われていbazFunc()ますが、私はその例しか見つけることができません.それを指定する関連するステートメントはまだ見つかりません:
例 15.12.4.1-2。メソッド呼び出し中の評価順序
インスタンス メソッドの呼び出し (§15.12) の一部として、呼び出されるオブジェクトを示す式があります。この式は、メソッド呼び出しに対する引数式の一部が評価される前に、完全に評価されるように見えます。たとえば、次のようになります。
class Test2 { public static void main(String[] args) { String s = "one"; if (s.startsWith(s = "two")) System.out.println("oops"); } }
sbeforeの出現は".startsWith"、引数 expression の前に最初に評価されますs = "two"。したがって、"one"ローカル変数 s が string を参照するように変更される前に、string への参照がターゲット参照として記憶されます"two"。その結果、 メソッドは引数 でstartsWithターゲット オブジェクトに対して呼び出され、文字列 が で始まらないため、呼び出しの結果は false になります。したがって、テスト プログラムは出力しません。"one""two""one""two""oops"
最初fooFuncに、次にbazFunc、そして最後にbarFunc
これを示すコードを次に示します。
public class OrderJava {
  public static void main(String[] args) {
    fooFunc().barFunc(bazFunc());
  }
  public static Bar fooFunc() {
    System.out.println("I am fooFunc!");
    return new Bar();
  }
  public static class Bar {
    public void barFunc(Object o) {
      System.out.println("I am barFunc!");
    }
  }
  public static Object bazFunc() {
    System.out.println("I am bazFunc!");
    return null;
  }
}
このコードの出力は次のとおりです。
I am fooFunc!
I am bazFunc!
I am barFunc!
    fooFunc()最初に実行され、続いてbazFunc()最後に実行されますbarFunc()
fooFunc()操作する前に実行する必要があることに誰もが同意できますbarFunc()。
パラメータが必要なbazFunc()場合にのみ呼び出されることを考えると、これが の後に発生するのは理にかなっています。barFunc()fooFunc()