Java是否在“ &&”(和)运算符中检查所有参数,即使其中一个是错误的?
-
09-10-2019 - |
题
我有这样的代码:
if(object != null && object.field != null){
object.field = "foo";
}
假设该对象为null。
此代码是否导致NullPoInterException或仅执行语句?
如果这样做,如何重构此代码以变得更加优雅(当然可以)?
解决方案
Java确实有短路评估,即您的代码应该可以
其他提示
&&
做短路时 &
不会。
但是,有了这样的简单问题,最好尝试一下(当您无法访问机器时,Ideone可以提供帮助)。
&& - http://ideone.com/lvv6w & - http://ideone.com/x5pdu
最后,检查的地方肯定是 JLS§15.23. 。相关部分指出,这不是最容易阅读的东西:&&运营商就像&(§15.22.2),但仅当其左手操作数的价值为真时,才能评估其右手操作。
找出发现的最佳方法是尝试一下,尤其是对于单行问题。也会更快。
答案是Java不会执行“如果”的主体。
这不会扔任何 NullPointerException
。条件将从左至右评估,并且首先要评估 false
表达发现它不会评估剩余的表达。
一种知道它的方法!测试!如何?好吧,制作一种打印出一些东西的方法:
public static boolean test(int i)
{
System.out.println(i);
return false;
}
...
if (test(1) && test(2) && test(3))
{
// not reached
}
此打印:
1
因此,您的问题的答案是“否”。
也许另一个问题可以帮助您:
Java具有短路评估,因此可以。
代码对我来说还不错,但是您实际上需要检查 object.field != null
?我认为可以省略该测试,因为您永远不会使用该变量,只需设置它即可。
在旁注上,大多数程序员不会直接访问字段(object.field
)而是通过getters/setter(object.setField(x);
)。没有更多的上下文,我不能说在您的情况下这是否合适。
&&和||条件停止在他们可以决定状况是否为真/错误的时刻停止,在您的情况下,情况将立即停止 object != null
我认为您的代码在这种情况下很好
如果您希望评估所有布尔表达式,而不管每个表达式的真实价值如何,则可以使用&| |而不是&&和||。但是,请确保仅在布尔表达式上使用它们。与&&和||,&&|还具有数字类型的含义,该含义与它们对布尔值的含义完全不同。http://ibiblio.org/java/course/week2/46.html
尽管在这里短路可以工作,但并不能保证(就像我做了很多次一样)您在编写另一个时会订购订单,但是如果陈述并定义您想要布尔值支票的订单,那将是更好的练习打破:
if(object != null)
{
if(object.field != null)
{
object.field = "foo";
}
}
这与您本质上的说法完全相同,如果第一个布尔检查失败不做第二次。它也是nullpoInterException安全,因为对象。除非对象不为空,否则不会检查字段
在布尔值上使用短路可能会变得令人讨厌,因为当您有多个布尔语言语句时,有效调试哪个部分短路变得更加棘手。