Java 是不是会检查“&&”(和)运算符中的所有参数,即使其中一个参数为假?
Posted
技术标签:
【中文标题】Java 是不是会检查“&&”(和)运算符中的所有参数,即使其中一个参数为假?【英文标题】:Does Java check all arguments in "&&" (and) operator even if one of them is false?Java 是否会检查“&&”(和)运算符中的所有参数,即使其中一个参数为假? 【发布时间】:2011-05-09 00:04:52 【问题描述】:我有这样的代码:
if(object != null && object.field != null)
object.field = "foo";
假设对象为空。
这段代码会导致 nullPointerException 还是 if 语句不会被执行?
如果可以,如何重构这段代码使其更优雅(当然如果可能的话)?
【问题讨论】:
玩转:ideone.com/KRMwj 另一种情况:ideone.com/NAP0Q 【参考方案1】:&&
会短路,而&
不会。
但是对于这样简单的问题,最好只是尝试一下(当您无法使用机器时,ideone 可以提供帮助)。
&& - http://ideone.com/LvV6w & - http://ideone.com/X5PdU
最后确定检查的地方是JLS §15.23。不是最容易阅读的东西,相关部分指出: && 运算符类似于 & (§15.22.2),但仅当其左侧操作数的值为真时才计算其右侧操作数。
【讨论】:
【参考方案2】:Java 确实有短路评估,即您的代码应该没问题
【讨论】:
Java 确实存在短路,但它仅在本示例中使用,因为使用了&&
而不是 &
。 &
将导致 NullPointerException
。
"&& 而不是 &"?您在问题的什么地方看到了这一点?
无处,我只是添加了这一点,因为&
运算符确实没有有短路。【参考方案3】:
找出答案的最佳方法是尝试一下,尤其是对于单行问题。也会更快。
答案是Java不会执行“if”的主体。
【讨论】:
没错,但“实验证明”并不总是最好的方法。例如,考虑在单核机器上测试与并发相关的东西。询问和理解底层机制总是好的,而不是希望你的测试包括黑盒的所有边缘情况...... 请记住,我们在这里讨论的是一行代码。 “边缘案例”?在这种情况下不是。【参考方案4】:这不会抛出任何 NullPointerException
。条件将从左到右进行计算,并且在找到第一个 false
表达式的那一刻,它不会计算剩余的表达式。
【讨论】:
【参考方案5】:一种了解它的方法!测试它!如何?好吧,制作一个打印出一些东西的方法:
public static boolean test(int i)
System.out.println(i);
return false;
...
if (test(1) && test(2) && test(3))
// not reached
这打印:
1
所以你的问题的答案是“否”。
【讨论】:
【参考方案6】:也许这个其他问题可以帮助你:
Differences in boolean operators: & vs && and | vs ||
【讨论】:
【参考方案7】:Java 有短路评估,所以没问题。
代码在我看来没问题,但你真的需要检查object.field != null
吗?我认为 test 可以省略,因为您从不使用变量,只需设置它。
附带说明,大多数程序员不会直接访问字段 (object.field
),而是通过 getter/setter (object.setField(x);
)。没有更多的上下文,我不能说这是否适合你的情况。
【讨论】:
【参考方案8】:&& 和 ||条件在他们可以决定条件是真/假的点停止,在您的情况下,条件将在object != null
之后立即停止,我认为您的代码对于这种情况来说很好
【讨论】:
【参考方案9】:如果您希望计算所有布尔表达式而不考虑每个表达式的真值,那么您可以使用 & 和 |而不是 && 和 ||。但是请确保仅在布尔表达式上使用这些。与 && 和 || 不同,& 和 |数字类型的含义也与布尔值的含义完全不同。 http://ibiblio.org/java/course/week2/46.html
【讨论】:
【参考方案10】:虽然短路可以在这里工作,但它不能保证(就像我多次做过的那样)你在编写另一个时会弄错顺序,最好嵌套这些 if 语句并定义你想要的顺序要打破的布尔检查:
if(object != null)
if(object.field != null)
object.field = "foo";
这与您本质上所说的完全相同,如果第一个布尔检查失败,则不要执行第二个;它也是 nullPointerException 安全的,因为除非 object 不为 null,否则不会检查 object.field
在布尔值上使用短路可能会在以后变得烦人,因为当您有多个 bool if 语句时,有效地调试哪个部分短路变得更加棘手。
【讨论】:
以上是关于Java 是不是会检查“&&”(和)运算符中的所有参数,即使其中一个参数为假?的主要内容,如果未能解决你的问题,请参考以下文章