简体   繁体   English

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

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

Given that: 鉴于:

Object x = null;

Consider code snippet #1: 考虑代码片段1:

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

Code snippet #1 does not throw a NullPointerException as I first thought it should have. 代码片段1不会像我最初认为的那样抛出NullPointerException I can provoke the exception with a little bit of help from the | 我可以在|的帮助下引发异常| operator. 操作员。 Code snippet #2: 代码片段2:

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

How come then that my first code snippet never evaluated the right expression that has a unary NOT operator in it (the exclamation ! )? 那么,为什么我的第一个代码片段从未评估过带有一元NOT运算符的正确表达式(感叹号! )? According to.. well all web sites out there.. the unary NOT operator has higher precedence that that of the logical OR operator ( || ). 根据..所有网站的描述,。一元NOT运算符的优先级高于逻辑OR运算符( || )的优先级。

the unary NOT operator has higher precedence that that of the logical OR operator (||). 一元NOT运算符的优先级高于逻辑OR运算符(||)的优先级。

Yes it's true. 对,是真的。 But the precedence thing will come into effect, if you use NOT on the first expression of logical OR. 但是,如果对逻辑OR的第一个表达式使用NOT,则优先级事项将生效。

Consider the condition: 考虑条件:

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

In this case, the negation will be applied first on the result of x.equals(y) , before the logical OR. 在这种情况下,将首先在逻辑或之前对x.equals(y)的结果应用否定。 So, had the precedence of || 因此,具有||的优先级 been greater than ! 大于! , then the expression would have been evaluated as: ,则该表达式将被评估为:

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

But it's not. 但事实并非如此。 As you know why. 如你所知。

However, if the NOT operator is on the second expression, the precedence is not a point here. 但是,如果NOT运算符位于第二个表达式上,则此处的优先级不是重点。 The first expression will always be evaluated first before the 2nd expression. 第一个表达式将始终在第二个表达式之前首先被求值。 And short-circuit behaviour will come into play. 短路行为将起作用。

It is a common misconception that precedence == order of evaluation. 一个普遍的误解是优先级==计算顺序。 This is not always the case. 这并非总是如此。 Precedence determines the order the compiler builds the expression and this can lead the code generated to match that order, but in some cases, eg post increment and short curcuit operators that this doesn't apply. 优先级确定编译器生成表达式的顺序,这可以使生成的代码与该顺序匹配,但是在某些情况下,例如,后增量和简短的curcurit运算符不适用。

All precedence means is to where the implied brackets are eg 所有优先级均指隐含括号的位置,例如

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

is the same as 是相同的

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

This is explained in this Java tutorial . 本Java教程对此进行了解释。 The || || and && short circuit execution if the first boolean expression results in true or false , respectively. 如果第一个布尔表达式的结果为truefalse ,则&&短路执行。

The unary ! 一元! has higher precedence than the bitwise OR | 具有比按位OR |高的优先级 . See here for precedence rules. 优先规则请参见此处

Read up on short-circuit evaluation - in the logical OR statement ( || ) the second argument is only evaluated if the first is false. 读取短路评估 -在逻辑OR语句( || )中,仅当第一个为false时才评估第二个参数。

With the second operator (a bitwise inclusive or , | ), both arguments are evaluated (it doesn't short-circuit). 使用第二个运算符( 按位包含或| ),两个参数都被求值(不会短路)。 Therefore, because x is null, the second one will throw a NullPointerException while the first won't. 因此,因为x为null,第二个将抛出NullPointerException而第一个则不会。

If Java is anything like C# on this front, logical operators like || 如果Java在这方面类似于C#,则逻辑运算符|| and && are evaluated left-to-right. &&从左到右求值。 if p == true then p OR q == true , by definition, so evaluating the right-hand of the OR is pointless. 如果p == truep OR q == true ,顾名思义,因此评估OR的右手是毫无意义的。

This is stops you having to do things like this (and, of course, is more efficient than evaluating a load of redundant expressions): 这使您不必做这样的事情(当然,它比评估冗余表达式的负载更有效):

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

I'm not really sure how precedence is relevant here, as the NOT excludes the first expression in the provided conditional, so the value of the right hand has no bearing on the value of the left hand anyway. 我不太确定这里的优先级有多重要,因为NOT排除了提供的条件中的第一个表达式,因此右手的值无论如何都与左手的值无关。

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

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