声明では:
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"); } }
s
beforeの出現は".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()