String foo = null;
if(foo == null || foo.equals("")){
//this is only safe if I'm guaranteed that the evaluation happens from left to right
}
在Java中,有这样的保证吗?或者我是否需要同时执行这些测试才能确定?
String foo = null;
if(foo == null || foo.equals("")){
//this is only safe if I'm guaranteed that the evaluation happens from left to right
}
在Java中,有这样的保证吗?或者我是否需要同时执行这些测试才能确定?
是的。从JLS 第 15.24 节:
条件或运算符运算
||
符类似于|
(§15.22.2),但仅当其左侧操作数的值为 false 时才评估其右侧操作数。
除非左侧操作数为真,否则右侧操作数甚至不会被计算,这意味着它必须从左到右进行计算……但事实上,所有运算符都是如此。从JLS 15.7开始:
Java 编程语言保证运算符的操作数看起来是以特定的评估顺序进行评估的,即从左到右。
方法(和构造函数)参数也是如此。例如,来自第 15.12.4.2 节(评估参数,方法调用的运行时评估的一部分):
参数表达式(如果有)按从左到右的顺序计算。如果任何参数表达式的求值突然完成,则其右侧的任何参数表达式的任何部分似乎都没有被求值,并且方法调用出于相同的原因突然完成。
(注意这里的“似乎”很有趣——JVM 可以无序地实际评估它们,只要这不是可观察到的......)
||
'&&'的顺序是从左到右。
对于||
运营商。如果它查看 if a||b
,如果a
是false
,它将检查b
.
如果左侧是,||
操作者将短路true
。左侧总是首先被评估。
是的,您可以保证这段代码是安全的:如果is ,它永远不会抛出NullPointerException。foo
null
仅供参考,您的代码片段是典型的 java 代码,是最佳实践。
是的,java 将使用 OR 运算符从左到右短路条件。
在运行时,首先计算左边的操作数表达式;如果结果具有布尔类型,则将进行拆箱转换(第 5.1.8 节)。
如果结果值为真,则条件或表达式的值为真,并且不计算右侧操作数表达式。
如果左侧操作数的值为 false,则计算右侧表达式;如果结果具有布尔类型,则将进行拆箱转换(第 5.1.8 节)。结果值成为条件或表达式的值。
答案是它取决于。
在你的情况下 - 是的,但一般来说这取决于运营商。
例如= (assign operator)求值是从右到左进行的
int a = 1;
int b = 2;
int c = 3;
a = b = c;
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("c = " + c);
结果:
a = 3
b = 3
c = 3
在这里您可以找到 Java 运算符的完整列表和评估顺序:http: //introcs.cs.princeton.edu/java/11precedence/
您的标题具有误导性。根据 JLS,您的实际问题的答案是“是”,但“所有评估都是从左到右进行的”绝对不是真的。
这是一个常见的误解。考虑表达式a+b*c
。JLS 实际上所说的评估顺序是运算符的操作数从左到右进行评估。因此a,b,c
,无论它们是什么,例如函数,都按该顺序进行评估。运算符是根据指定的运算符优先级应用的(在 JLS 中实际上并没有很好地指定)。所以当然乘法发生在加法之前。