Java中布尔表达式的求值顺序是什么?

25

假设我有以下表达式:

String myString = getStringFromSomeExternalSource();
if (myString != null && myString.trim().length() != 0) {
...
}

Eclipse警告我,在布尔表达式的第二个短语中myString可能为null。然而,我知道有些编译器如果第一个条件失败,则会完全退出布尔表达式。Java也是这样吗?或者求值的顺序不能保证?


你正在使用哪个编译器或工具? - notnoop
好的,javac(最常见的编译器)不会警告空值。如果“Java警告我的字符串可能为空”,那很可能是一个有缺陷的工具。没有所谓的“Java警告”。 - notnoop
没错,@notnoop。我在使用Eclipse。我的代码写得有点马虎。 - daveslab
在Eclipse中,我只能通过||操作或'myString == null'来重现警告。您确定Eclipse对此代码片段发出了警告吗? - notnoop
4个回答

47

然而,我知道有些编译器如果第一个条件失败,就会完全退出布尔表达式。Java也是这样吗?

是的,这被称为短路求值。像&&||这样的运算符执行此类操作。

或者说,评估顺序不能保证吗?

不,评估顺序是有保证的(从左到右)。


8

Java应该从左到右评估您的语句。它使用一种被称为短路求值的机制,以防止第二个、第三个和第n个条件在第一个条件为false时被测试。

因此,如果您的表达式是myContainer != null && myContainer.Contains(myObject)并且myContainer为空,则第二个条件myContainer.Contains(myObject)将不会被评估。

编辑:正如其他人提到的,特别是对于布尔条件,Java确实具有短路和非短路运算符。使用&&将触发短路求值,而&则不会。


1
引用:“如果第一个条件为假,则防止测试第二个、第三个和第n个条件。” 实际上,如果运算符是 ||,则编译器无法仅从第一个条件得出整个值,如果第一个条件为 false。 - H2ONaCl

2

James和Ed都是正确的。如果你遇到一个情况,希望所有表达式都被评估而不考虑之前失败的条件,你可以使用非短路布尔运算符&


1
是的,Java在if语句中使用了惰性求值。如果myString==null,那么if语句的剩余部分将不会被求值。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接