我有这样的代码:
if(object != null && object.field != null){
object.field = "foo";
}
假设对象为空。
此代码是否导致 nullPointerException 或 if 语句不会被执行?
如果是这样,如何重构此代码以使其更优雅(当然,如果可能的话)?
我有这样的代码:
if(object != null && object.field != null){
object.field = "foo";
}
假设对象为空。
此代码是否导致 nullPointerException 或 if 语句不会被执行?
如果是这样,如何重构此代码以使其更优雅(当然,如果可能的话)?
&&
会短路而&
不会。
但是对于这样的简单问题,最好只是尝试一下(当您无法访问机器时,ideone 可以提供帮助)。
&& - http://ideone.com/LvV6w & - http://ideone.com/X5PdU
最后要检查的地方是JLS §15.23。不是最容易阅读的内容,相关部分指出: && 运算符类似于 & ( §15.22.2 ),但仅当其左侧操作数的值为真时才评估其右侧操作数。
Java确实有短路评估,即你的代码应该没问题
一种方法来了解它!测试它!如何?好吧,制作一个打印出一些东西的方法:
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
吗?我认为 test 可以省略,因为您从不使用变量,只需设置它。
附带说明一下,大多数程序员不会直接访问字段(object.field
),而是通过 getter/setter(object.setField(x);
)。没有更多的上下文,我不能说这是否适合你的情况。
&& 和 || 条件在他们可以决定条件是真/假时停止,在你的情况下,条件将在之后停止object != null
,我认为你的代码适合这种情况
如果您希望评估所有布尔表达式而不管每个表达式的真值,那么您可以使用 & 和 | 而不是 && 和 ||。但是请确保仅在布尔表达式上使用这些。与 && 和 || 不同,& 和 | 数字类型的含义也与布尔值的含义完全不同。 http://ibiblio.org/java/course/week2/46.html
虽然短路可以在这里工作,但它不能保证(就像我已经做过很多次一样)在编写另一个时你会得到错误的顺序,最好嵌套那些 if 语句并定义你想要布尔检查的顺序打破:
if(object != null)
{
if(object.field != null)
{
object.field = "foo";
}
}
这与您本质上所说的完全相同,如果第一个布尔检查失败,则不要执行第二个;它也是 nullPointerException 安全的,因为除非 object 不为 null,否则不会检查 object.field
在布尔值上使用短路可能会在以后变得烦人,因为当您有多个 bool if 语句时,有效地调试哪个部分短路变得更加棘手。