为什么逻辑运算符会更改对象

why the logical operators change the object

为什么当我使用下面的代码时,eclipse 会用红色突出显示 (!line.equals("")) 并说:空指针访问:变量行在此位置只能为空

但如果我使用 : && 而不是 ||?

,我不会收到该警告消息

代码:

String line = br.readLine();
        if ( (line != null) || (!line.equals("")) ) {
        } else {
            Log.d(TAG, "main", "file is empty");
        }

因为&&(逻辑与)将按顺序检查条件,如果任何条件为假,则不会检查下一个条件。其中 ||(逻辑或)将检查直到其中一个条件为真。

所以如果你使用 || 有可能第一个条件(即 line != null)为假,它会转到下一个条件(即 !line.equals(""))并抛出 NullPointerException.

并且 @piet.t 正确地指出,如果第一个条件为真,那么如果您使用 ||,它也不会进行空白检查。


您可能还对Difference between & and && in Java?

感兴趣

因为您有一个 OR (||) 运算符,Java 将确定

的值
line != null

如果这是错误的(如果行 空)

!line.equals("")

因此当 line 为空时将执行第二个,并解引用一个空指针。您的 IDE 正确地突出了这个问题。

是因为运算符|| Java 必须评估给出结果的两个条件。当 Java 将尝试第二个条件时,他将失败并返回 npe。

因为在 && 的情况下 !line.equals("") 仅在 line != null 为真时才被检查,不像 ||line != null 为真时编译器会检查 !line.equals("") 语句并退出 if()

&& 是一个 "short-circuit" 运算符。这意味着,如果左侧条件(行!= null)失败,则不会评估右侧条件,因此不存在 NullPointerException 的风险。要确定 OR 的结果,必须评估两个条件(无论短路运算符如何)。因此警告。

这是经典"short circuit"。

对于 && 案例:

if ((line != null) && (!line.equals("")) {

如果 line 确实等于 null,则编译器没有理由处理 if 语句的第二部分。整个 if 语句必须为假。所以它短路了 if 语句的第二部分,你不会得到空引用异常。

当您将 && 切换为 || 时,编译器必须处理 if 语句的第二部分,因为如果任何一部分为真,那么整个事情都为真。因此,可以得到空引用异常。

注意:如果你也可以使用 Apache commons-lang 的 StringUtils 来同时检查一个:

if (StringUtils.isNotBlank(str))

更新:对于||情况下,如果第一部分为真,则整个 if 语句必须为真,因此同样没有理由处理 if 语句的第二部分。