1

鉴于:

Object x = null;

考虑代码片段#1:

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

代码片段 #1 并没有NullPointerException像我最初认为的那样抛出 a 。我可以在操作员的一点帮助下引发异常|。代码片段#2:

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

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

4

5 回答 5

7

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

对,是真的。但是,如果在逻辑 OR 的第一个表达式上使用 NOT,优先级就会生效。

考虑条件:

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

在这种情况下,否定将首先应用于 的结果x.equals(y),然后再进行逻辑 OR。因此,如果 的优先级||大于!,则表达式将被计算为:

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

但事实并非如此。你知道为什么。

但是,如果 NOT 运算符在第二个表达式上,则此处的优先级不是一个点。第一个表达式总是在第二个表达式之前首先被计算。短路行为将发挥作用。

于 2013-09-02T14:57:08.420 回答
4

优先级 == 评估顺序是一个常见的误解。这并非总是如此。优先级决定了编译器构建表达式的顺序,这可以导致生成的代码与该顺序相匹配,但在某些情况下,例如后递增和短 curcuit 运算符不适用。

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

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

是相同的

if ((x == null) || (!(x.equals(new Object()))))
于 2013-09-02T15:01:32.913 回答
0

这在本 Java 教程中进行了解释。如果第一个布尔表达式分别导致or ,则||&&短路执行。truefalse

一元!的优先级高于按位 OR |。请参阅此处了解优先规则。

于 2013-09-02T14:55:44.720 回答
0

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

使用第二个运算符(按位包含或, |),计算两个参数(它不会短路)。因此,因为x是 null,第二个会抛出一段NullPointerException时间,第一个不会。

于 2013-09-02T14:56:02.493 回答
0

如果 Java 在这方面类似于 C#,那么逻辑运算符喜欢||&&从左到右进行评估。如果p == truethen p OR q == true,根据定义,因此评估 the 的右手OR是没有意义的。

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

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

我不确定优先级在这里的相关性如何,因为NOT排除了提供的条件中的第一个表达式,所以右手的值无论如何都与左手的值无关。

于 2013-09-02T14:56:49.457 回答