繁体   English   中英

Java的逻辑OR运算符不评估右侧,尽管右侧具有一元运算符?

[英]Java's logical OR operator does not evaluate right hand side despite that right hand side has a unary operator?

鉴于:

Object x = null;

考虑代码片段1:

if (x == null || !x.equals(new Object()))
    System.out.println("I print!");

代码片段1不会像我最初认为的那样抛出NullPointerException 我可以在|的帮助下引发异常| 操作员。 代码片段2:

if (x == null | !x.equals(new Object()))
    System.out.println("This will throw a NullPointerException..");

那么,为什么我的第一个代码片段从未评估过带有一元NOT运算符的正确表达式(感叹号! )? 根据..所有网站的描述,。一元NOT运算符的优先级高于逻辑OR运算符( || )的优先级。

一元NOT运算符的优先级高于逻辑OR运算符(||)的优先级。

对,是真的。 但是,如果对逻辑OR的第一个表达式使用NOT,则优先级事项将生效。

考虑条件:

if (!x.equals(y) || y.equals(z))

在这种情况下,将首先在逻辑或之前对x.equals(y)的结果应用否定。 因此,具有||的优先级 大于! ,则该表达式将被评估为:

if (!(x.equals(y) || y.equals(z)))

但事实并非如此。 如你所知。

但是,如果NOT运算符位于第二个表达式上,则此处的优先级不是重点。 第一个表达式将始终在第二个表达式之前首先被求值。 短路行为将起作用。

一个普遍的误解是优先级==计算顺序。 这并非总是如此。 优先级确定编译器生成表达式的顺序,这可以使生成的代码与该顺序匹配,但是在某些情况下,例如,后增量和简短的curcurit运算符不适用。

所有优先级均指隐含括号的位置,例如

if (x == null || !x.equals(new Object()))

是相同的

if ((x == null) || (!(x.equals(new Object()))))

本Java教程对此进行了解释。 || 如果第一个布尔表达式的结果为truefalse ,则&&短路执行。

一元! 具有比按位OR |高的优先级 优先规则请参见此处

读取短路评估 -在逻辑OR语句( || )中,仅当第一个为false时才评估第二个参数。

使用第二个运算符( 按位包含或| ),两个参数都被求值(不会短路)。 因此,因为x为null,第二个将抛出NullPointerException而第一个则不会。

如果Java在这方面类似于C#,则逻辑运算符|| &&从左到右求值。 如果p == truep OR q == true ,顾名思义,因此评估OR的右手是毫无意义的。

这使您不必做这样的事情(当然,它比评估冗余表达式的负载更有效):

if (x != null)
{
    if (x.Property > 0)
    {
        ....
    }
}

我不太确定这里的优先级有多重要,因为NOT排除了提供的条件中的第一个表达式,因此右手的值无论如何都与左手的值无关。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM