繁体   English   中英

评估尊重括号和优先权 - java

[英]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

编译器首先将哪个运算符“绑定”到参数? 如果+具有更高的优先级,它会在*之前抓住它附近的参数,可以这么说; 这样结果就是添加了bc ,结果乘以a 也就是说,它等同于

a * (b + c)

但在大多数编程语言中(有一些例外,如APL), *具有更高的优先级。 这意味着参数在绑定到+之前绑定到* ,这意味着ab相乘,并且结果被添加到c ,即

(a * b) + c

同样,在表达式中

a + b * c

结果是bc相乘,结果加到a

a + (b * c)

您可以在表达式的某些部分周围加上括号来更改参数的绑定方式; 因此,如果你想添加ab并将总和乘以c ,你可以说

(a + b) * c

但是需要注意的是:所有这些都控制在编译时如何解释表达式。 但是在运行时,参数总是从左到右进行评估。 当程序运行时,所有上述表达式将导致程序评估a ,然后是b ,然后是c 如果abc是变量,这无关紧要,但如果它们是方法调用,则可能很重要。 在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)ab的值无关,它们不被评估(并且不应用增量)。

它将与(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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM