[英]Evaluation Respects Parentheses and Precedence - java
根据Java语言规范:
评估尊重括号和优先顺序
除了使用数学运算之外:
int i = 3;
int j = 3 * (9 + 3);
System.out.println(j); //results to 36
该规则是否适用于其他任何示例? 我试过用
int i = 0;
int z = 0;
if(i++ < 5 || (++z <0 && 5 > z++) || 6 < ++i){
System.out.println("Routed here");
}
System.out.println("i: " + i);
System.out.println("z: " + z);
但结果是i:1和z:0。 似乎对该示例的评估仍然是从左到右。
随着||
,Java在评估表达式时使用了短路的概念。 因此,在这:
if(i++ < 5 || (++z <0 && 5 > z++) || 6 < ++i){
因为第一个表达式i++ < 5
返回true,因此表达式的其余部分将不会被评估,即从未被访问过,因此只会在i
的值中带来变化,而不会有任何其他东西。
来自Java Docs的引用:
条件运算符&&和|| 运算符对两个布尔表达式执行条件AND和条件OR运算。 这些运算符表现出“短路”行为,这意味着仅在需要时才评估第二个操作数。 && Conditional-AND || Conditional-OR以下程序ConditionalDemo1测试这些运算符:
class ConditionalDemo1 {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
if((value1 == 1) && (value2 == 2))
System.out.println("value1 is 1 AND value2 is 2");
if((value1 == 1) || (value2 == 1))
System.out.println("value1 is 1 OR value2 is 1");
}
}
括号和优先级与运行时计算表达式的顺序无关。 也就是说,如果您认为在表达式周围加括号意味着它将在之前得到评估,或者更早地评估具有更高优先级的运算符,那么您就会误解这个概念。
运算符优先级回答如下问题:在表达式中
a * b + c
编译器首先将哪个运算符“绑定”到参数? 如果+
具有更高的优先级,它会在*
之前抓住它附近的参数,可以这么说; 这样结果就是添加了b
和c
,结果乘以a
。 也就是说,它等同于
a * (b + c)
但在大多数编程语言中(有一些例外,如APL), *
具有更高的优先级。 这意味着参数在绑定到+
之前绑定到*
,这意味着a
和b
相乘,并且结果被添加到c
,即
(a * b) + c
同样,在表达式中
a + b * c
结果是b
和c
相乘,结果加到a
。
a + (b * c)
您可以在表达式的某些部分周围加上括号来更改参数的绑定方式; 因此,如果你想添加a
和b
并将总和乘以c
,你可以说
(a + b) * c
但是需要注意的是:所有这些都控制着在编译时如何解释表达式。 但是在运行时,参数总是从左到右进行评估。 当程序运行时,所有上述表达式将导致程序评估a
,然后是b
,然后是c
。 如果a
, b
和c
是变量,这无关紧要,但如果它们是方法调用,则可能很重要。 在Java中,当程序运行时,事物总是从左到右进行评估。 (其他语言并非如此;我所知道的大多数语言都让编译器选择顺序。)
当涉及到||
和&&
(或其他一些语言中的类似运算符),再次在运行时, 始终首先计算左参数。 可能会或可能不会评估正确的参数。 如果你有一个像some-expression-1 || some-expression-2 && some-expression-3
这样some-expression-1 || some-expression-2 && some-expression-3
括号和运算符优先级控制表达式的解释方式 some-expression-1 || some-expression-2 && some-expression-3
,但它们不会在运行时更改评估顺序。
只要测试可以被评估为true或false,执行就会在if块内跳转。 在你的情况下, i
等于0
,它比5
轻,所以测试评估为true
。
(true OR a OR b)
与a
和b
的值无关,它们不被评估(并且不应用增量)。
它将与(false AND a AND b)
相同,除非它总是跳过块。
检查表达式的顺序,将它们分成单独的测试或从测试中获得增量。 以下代码等同于您的示例,但具有您期望的输出:
int i = 0;
int z = 1;
if(i < 5 || (z < 0 && 5 > z+2) || 6 < i+2){
System.out.println("Routed here");
}
i += 2;
z += 2;
System.out.println("i: " + i);
System.out.println("z: " + z);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.