我有这样一段代码:
if(object != null && object.field != null){
object.field = "foo";
}
假设对象为null。
这段代码会导致nullPointerException还是if语句不会被执行?
如果会,如何重构这段代码使其更加优雅(如果可能的话)?
我有这样一段代码:
if(object != null && object.field != null){
object.field = "foo";
}
假设对象为null。
这段代码会导致nullPointerException还是if语句不会被执行?
如果会,如何重构这段代码使其更加优雅(如果可能的话)?
&&
在短路的时候会停止计算,而&
则不会。
但对于像这样简单的问题,最好还是自己试一下(当你没有机器可以使用时,ideone可以提供帮助)。
&& - http://ideone.com/LvV6w & - http://ideone.com/X5PdU
最后,确认答案的最佳途径是参考JLS §15.23。尽管不太容易阅读,但相关章节说明如下: &&运算符类似于&(§15.22.2),但只有左操作数的值为true时才计算右操作数的值。
Java具有短路运算,即您的代码应该没问题。
&&
而不是&
。如果用&
,会导致空指针异常。 - Captain Man&
运算符没有短路。 - Captain Man了解它的一种方法是测试它!怎么测试呢?好的,制作一个打印输出内容的方法:
public static boolean test(int i)
{
System.out.println(i);
return false;
}
...
if (test(1) && test(2) && test(3))
{
// not reached
}
1
最好的方法是尝试一下,特别是对于一个单行问题。这样做会更快。
答案是Java不会执行“if”的主体。
NullPointerException
异常。条件从左到右依次进行评估,一旦发现第一个false
表达式,剩余的表达式将不再被评估。Java有短路求值,所以这没问题。
代码看起来没问题,但你真的需要检查object.field != null
吗?我认为可以省略该测试,因为你从未使用该变量,只是设置它。
顺便说一下,大多数程序员不会直接访问字段(object.field
),而是通过getter/setter(object.setField(x);
)进行访问。没有更多上下文可供参考,我无法确定在你的情况下是否适用。
&& 和 || 条件会在它们能够确定条件是真/假的时候停止,对于你的情况,条件将在 object != null
后立即停止,我认为你的代码在这种情况下很好。
虽然短路计算在这里可以工作,但并不能保证(就像我经常做的那样)在编写另一个语句时不会出现顺序错误。更好的做法是嵌套这些if语句并定义您希望布尔检查中断的顺序:
if(object != null)
{
if(object.field != null)
{
object.field = "foo";
}
}
这段代码的作用与你所说的完全相同,如果第一个布尔检查失败,则不执行第二个;同时它也是空指针安全的,因为只有在对象不为空时才会检查 object.field。
在布尔值上使用短路运算符后期可能会变得很麻烦,因为当你有多个布尔 if 语句时,要有效地调试哪一部分被短路了就变得更加棘手。