在Java中描述实例和参数的方法的执行顺序?
在声明中:
fooFunc().barFunc(bazFunc());
barFunc()
显然不会执行,直到bazFunc()
和fooFunc()
都完成。
但是fooFunc()
和bazFunc()
的执行顺序是否有保证?
相关(但不同!)问题: Java中参数的执行顺序保证?
这方面的文件是15.12.4。 方法调用的运行时评估
它说“在运行时,方法调用需要五个步骤。首先,可以计算目标引用。其次,计算参数表达式。第三,检查要调用的方法的可访问性。第四,实际的代码找到要执行的方法。第五,创建新的激活帧,必要时执行同步,并将控制转移到方法代码。
在示例中, fooFunc()
被调用作为计算目标引用的一部分,而bazFunc()
是参数表达式之一,因此必须首先调用fooFunc()
。
JLS ,Java SE 7版有以下示例,它在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 = "two"
之前,首先计算".startsWith"
之前的s = "two"
。 因此,在将局部变量s改变为引用字符串"two"
之前,将记住对字符串"one"
的引用作为目标引用。 因此,对于具有参数"two"
目标对象"one"
,调用了startsWith
方法,因此调用的结果为false,因为字符串"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()
执行fooFunc()
,然后执行bazFunc()
,最后执行barFunc()
我们都同意fooFunc()
必须在barFunc()
有任何操作之前执行。
鉴于只有在barFunc()
需要它的参数时barFunc()
调用barFunc()
,因此在fooFunc()
之后会发生这种情况。