如果其中一个函数没有返回true,java会在运行时实际调用所有三个函数吗?
通常出于调试目的,我喜欢在调试器中看到这些条件检查的结果,并将它们放在一行中会使事情变得更加困难。如果有六个检查,则代码变得更难以理解。
boolean result1 = CheckSomething();
boolean result2 = CheckSomethingElse();
boolean result3 = CheckSomeOtherThing();
boolean finalResult = result1 && result2 && result3;
如果Java在运行时没有优化这个条件,那么应该通过编写这样的代码来实现更好的性能,代价是不能在调试器中轻松看到中间值。
boolean finalResult = CheckSomething() && CheckSomethingElse() && CheckSomeOtherThing();
答案 0 :(得分:2)
你可以这样写:
boolean result1 = condition1();
boolean result2 = result1 && condition2();
boolean result3 = result2 && condition3();
这允许您逐步执行每个条件,并在不执行不必要的代码的情况下查看中间结果。
您还可以在result3
行后设置一个断点,该行显示返回的第一个结果false
。
答案 1 :(得分:2)
通常您的代码段不等效。第一个版本必须表现为 as-if 所有函数都被调用,因为你在代码中无条件地调用它们。
代码的第二个版本:
boolean finalResult = CheckSomething() && CheckSomethingElse() && CheckSomeOtherThing();
不等效,因为&&
操作是快捷方式,因此如果任何返回false,则不会调用其余的函数。
在解释器中运行时,您可以预期代码的第一个版本将实际调用所有方法。
现在,有趣的部分:在编译代码之后,编译器现在能够"查看"各种函数确定它们是纯函数,没有副作用,并且它可以相同地编译这两个版本。实际上,如果函数非常简单,那么编译两个版本到总是调用所有三个函数可能会更好,因为组合三个布尔结果并检查一次可能是如果任何结果不可预测,会快得多。
编译器可能无法始终确定某个函数是否具有副作用,或者实际上可能存在只有您知道不重要的副作用(例如,您知道不会发生的ArrayOutOfBoundsException)但编译器无法证明)。因此,编写第二种形式通常会更好,这使得编译器可以使用短路评估,而不管它能够证明哪些功能。
答案 2 :(得分:0)
同意,第二个例子将继续评估,直到它达到错误状态,然后它将返回“false”。短路操作员&&正在使用,因此一旦遇到错误情况,评估就会停止。