Java 在块中连续使用相同的方法会重新计算该方法吗?

Java 在块中连续使用相同的方法会重新计算该方法吗?,java,methods,compiler-construction,jvm,repeat,Java,Methods,Compiler Construction,Jvm,Repeat,我一直假设每次在Java中调用一个方法时,该方法都会再次执行。我假设返回值不会自动存储,除非我将其存储在变量中 然后我遇到了这段代码,其中他们分别调用三个方法两次: private boolean check() { if (!isBST()) StdOut.println("Not in symmetric order"); if (!isSizeConsistent()) StdOut.println("Subtree counts not consis

我一直假设每次在Java中调用一个方法时,该方法都会再次执行。我假设返回值不会自动存储,除非我将其存储在变量中

然后我遇到了这段代码,其中他们分别调用三个方法两次:

private boolean check() {
    if (!isBST())            StdOut.println("Not in symmetric order");
    if (!isSizeConsistent()) StdOut.println("Subtree counts not consistent");
    if (!isRankConsistent()) StdOut.println("Ranks not consistent");
    return isBST() && isSizeConsistent() && isRankConsistent();
}
他们只是不关心性能吗?或者编译器是否足够聪明,可以在return语句中保留每个方法的第一个返回值

很抱歉,如果这是一个重复的答案似乎应该存在,但我在这里或Java文档中找不到它。我找到了这些(和其他),但它们没有回答我的问题:


Java语言规范明确且无条件地声明,方法调用表达式的计算涉及执行指定方法的代码。JLS 8是这样说的:

在运行时,方法调用需要五个步骤。首先是目标 可计算参考值。其次,参数表达式是 评价的。第三,要调用的方法的可访问性是 选中的。第四,要执行的方法的实际代码是 位于。第五,创建新的激活帧,同步 必要时执行,控制转移到方法代码

(;增加强调)

因此,第二次调用方法会导致第二次调用的成本,而不管是否可以预期计算相同的值。可以想象,JIT编译可以优化这一点,但是除了是否要计算相同的结果之外,还有更多的考虑因素,而且您不太可能看到任何JIT操作仅由给定方法的两次调用触发


一句话:是的,代码的作者根本不关心性能。他们可能认为所提供的实现比避免冗余方法调用的实现更清晰,或者他们可能有其他个人原因来选择。这种对实用性的忽视在为学术目的服务的代码中并不少见,如本文所述。

Java语言规范明确且无条件地声明,方法调用表达式的评估涉及执行指定方法的代码。JLS 8是这样说的:

在运行时,方法调用需要五个步骤。首先是目标 可计算参考值。其次,参数表达式是 评价的。第三,要调用的方法的可访问性是 选中的。第四,要执行的方法的实际代码是 位于。第五,创建新的激活帧,同步 必要时执行,控制转移到方法代码

(;增加强调)

因此,第二次调用方法会导致第二次调用的成本,而不管是否可以预期计算相同的值。可以想象,JIT编译可以优化这一点,但是除了是否要计算相同的结果之外,还有更多的考虑因素,而且您不太可能看到任何JIT操作仅由给定方法的两次调用触发


一句话:是的,代码的作者根本不关心性能。他们可能认为所提供的实现比避免冗余方法调用的实现更清晰,或者他们可能有其他个人原因来选择。这种对实用性的漠视在用于学术目的的代码中并不少见,例如所呈现的代码。

该代码中的
check
函数仅在上下文中调用:

assert check();
断言通常不会在生产代码中启用,如果断言未启用,
assert
语句绝对不会执行任何操作。因此,
check
功能将仅在调试运行时运行。这一事实并不意味着许可证是任意低效的,但通常不尝试优化此类代码。作为断言运行的代码的要点是,当它验证一个不变量、前置条件或后置条件时,显然是无可辩驳的正确的,而优化——即使是像将结果保存在局部变量中这样的琐碎优化——也无助于实现这一目标

断言是包含布尔表达式的断言语句。断言被启用或禁用。如果启用了断言,则执行断言会导致对布尔表达式求值,如果表达式求值为false,则会报告错误。如果断言被禁用,那么断言的执行将毫无效果


该代码中的
check
函数仅在上下文中调用:

assert check();
断言通常不会在生产代码中启用,如果断言未启用,
assert
语句绝对不会执行任何操作。因此,
check
功能将仅在调试运行时运行。这一事实并不意味着许可证是任意低效的,但通常不尝试优化此类代码。作为断言运行的代码的要点是,当它验证一个不变量、前置条件或后置条件时,显然是无可辩驳的正确的,而优化——即使是像将结果保存在局部变量中这样的琐碎优化——也无助于实现这一目标

断言是包含布尔表达式的断言语句。断言被启用或禁用。如果启用了断言,则执行断言会导致对布尔表达式求值,如果表达式求值为false,则会报告错误。如果断言被禁用,那么断言的执行将毫无效果


他们不关心业绩。编写该代码的人可能也有函数编程的倾向,因此他们觉得将结果存储在变量中是不愉快的。这并没有改变这样一个事实,即再次调用相同的方法将再次产生成本,并且