与三元运算符的Java布尔优先级比较

ksz*_*sze 3 java boolean operator-precedence comparator

我找到了一个很好的情况,我完全不了解Java布尔运算符优先级.我知道,并与Oracle的官方文件确认这里是&&和|| 优先于三元运算符?:

现在我在我的代码中有一个类似的奇怪的行

if (a.getItem() != null && a.getItem().getOtherItem() != null?true:a.getItem().getOtherItem().getSomevalue())
{
......
}
Run Code Online (Sandbox Code Playgroud)

我得到的是,a.getItem()上的一个很好的java.lang.NullPointerException.getOtherItem()因为a.getItem()是null.我如何解决它,将其封装在括号之间

if (a.getItem() != null && (a.getItem().getOtherItem() != null?true:a.getItem().getOtherItem().getSomevalue()))
{
......
}
Run Code Online (Sandbox Code Playgroud)

所以我的问题是为什么我得到一个NullPointerException如果我遵循以前链接的Oficial文档&&优先于?:和&&是短路评估(在一些问题中也回答).

Hol*_*ger 6

看来你对"更高优先级"的含义感到困惑.让我们用一个简单的例子来解释:

运算符的*优先级高于运算符"+".这意味着表达式a*b+c的评估方式如下(a*b)+c.这同样适用于&&运算符和三元运算符:

&&优先级高于运算符? :.这意味着表达式a&&b?c:d被评估为(a&&b)?c:d.


因此,运算符优先级的工作方式与示例中记录的相同.它完全符合您的要求:

if (a.getItem() != null && a.getItem().getOtherItem() != null?
                                       true:a.getItem().getOtherItem().getSomevalue())
Run Code Online (Sandbox Code Playgroud)

如果a.getItem() 不为null并且 a.getItem().getOtherItem() 不为null计算结果为,否则a.getItem().getOtherItem().getSomevalue().因此,当其中任何一个值为null时,代码将尝试计算将产生a的第三个项NullPointerException.

目前尚不清楚你真正想要实现的目标.在你的第二个例子中,你说:

if (a.getItem() != null && (a.getItem().getOtherItem() != null?
                            true: a.getItem().getOtherItem().getSomevalue()))
Run Code Online (Sandbox Code Playgroud)

所以你要解释的情况下a.getItem()null作为false,但在长期支撑你请求时,解释的情况下a.getItem().getOtherItem()是不null作为true,而该案件a.getItem().getOtherItem() null应该引起getSomevalue()您刚刚已经被证明是参考被称为null.

您最可能想要做的是评估a.getItem().getOtherItem().getSomevalue() 所有值是否为空:

if (a.getItem() != null && a.getItem().getOtherItem() != null?
                                     a.getItem().getOtherItem().getSomevalue(): false)
Run Code Online (Sandbox Code Playgroud)

请注意,您可以在没有三元运算符的情况下表达相同的内容.等同的陈述是:

if (a.getItem() != null && a.getItem().getOtherItem() != null
                        && a.getItem().getOtherItem().getSomevalue())
Run Code Online (Sandbox Code Playgroud)

在这种情况下,回落值应该true

if (a.getItem() != null && a.getItem().getOtherItem() != null?
                                     a.getItem().getOtherItem().getSomevalue(): true)
Run Code Online (Sandbox Code Playgroud)

同样可以表示为

if (a.getItem() == null || a.getItem().getOtherItem() == null
                        || a.getItem().getOtherItem().getSomevalue())
Run Code Online (Sandbox Code Playgroud)

无论何时看到truefalse在复合boolean表达式中,您都可以确定存在错误.