14

我有这样的代码:

if(object != null && object.field != null){
    object.field = "foo";
}

假设对象为空。

此代码是否导致 nullPointerException 或 if 语句不会被执行?

如果是这样,如何重构此代码以使其更优雅(当然,如果可能的话)?

4

10 回答 10

20

&&会短路而&不会。

但是对于这样的简单问题,最好只是尝试一下(当您无法访问机器时,ideone 可以提供帮助)。

&& - http://ideone.com/LvV6w & - http://ideone.com/X5PdU

最后要检查的地方是JLS §15.23。不是最容易阅读的内容,相关部分指出: && 运算符类似于 & ( §15.22.2 ),但仅当其左侧操作数的值为真时才评估其右侧操作数。

于 2010-11-12T10:40:19.503 回答
10

Java确实有短路评估,即你的代码应该没问题

于 2010-11-12T10:40:02.997 回答
3

一种方法来了解它!测试它!如何?好吧,制作一个打印出一些东西的方法:

public static boolean test(int i)
{
    System.out.println(i);
    return false;
}

...

if (test(1) && test(2) && test(3))
{
    // not reached
}

这打印:

1

所以你的问题的答案是“不”。

于 2010-11-12T10:50:30.780 回答
2

找出答案的最佳方法是尝试一下,尤其是对于单行问题。也会更快。

答案是Java 不会执行“if”的主体。

于 2010-11-12T10:40:33.370 回答
2

这不会抛出任何NullPointerException. 条件将从左到右进行评估,false一旦找到第一个表达式,它就不会评估剩余的表达式。

于 2010-11-12T10:41:21.513 回答
2

也许这个其他问题可以帮助你:

布尔运算符的区别:& vs && 和 | 与 ||

于 2010-11-12T13:31:59.177 回答
1

Java有短路评估,所以没问题。

代码对我来说看起来不错,但你真的需要检查object.field != null吗?我认为 test 可以省略,因为您从不使用变量,只需设置它。

附带说明一下,大多数程序员不会直接访问字段(object.field),而是通过 getter/setter(object.setField(x);)。没有更多的上下文,我不能说这是否适合你的情况。

于 2010-11-12T10:41:29.363 回答
1

&& 和 || 条件在他们可以决定条件是真/假时停止,在你的情况下,条件将在之后停止object != null,我认为你的代码适合这种情况

于 2010-11-12T10:43:55.677 回答
0

如果您希望评估所有布尔表达式而不管每个表达式的真值,那么您可以使用 & 和 | 而不是 && 和 ||。但是请确保仅在布尔表达式上使用这些。与 && 和 || 不同,& 和 | 数字类型的含义也与布尔值的含义完全不同。 http://ibiblio.org/java/course/week2/46.html

于 2010-11-12T10:42:06.383 回答
0

虽然短路可以在这里工作,但它不能保证(就像我已经做过很多次一样)在编写另一个时你会得到错误的顺序,最好嵌套那些 if 语句并定义你想要布尔检查的顺序打破:

if(object != null) 
{
    if(object.field != null)
    {
        object.field = "foo";
    }
}

这与您本质上所说的完全相同,如果第一个布尔检查失败,则不要执行第二个;它也是 nullPointerException 安全的,因为除非 object 不为 null,否则不会检查 object.field

在布尔值上使用短路可能会在以后变得烦人,因为当您有多个 bool if 语句时,有效地调试哪个部分短路变得更加棘手。

于 2010-11-12T10:45:32.997 回答