java中的一元运算符优先级

时间:2017-05-12 14:33:01

标签: java operators

现在,根据this网站,一元后增量优先于一元预增量。我认为这意味着x++++x之前完成。

然而,当尝试使用以下表达式时,我遇到了问题

int var1=10; 
int b= --var1 + ++var1 + var1++;

现在,如果var1++先执行,那么根据我,

b = --var1 + ++var1 + 10   

现在,如果我认为它应该在++var1之前--var1,因为它提到关联性从右到左。我想,这意味着在左边的那些东西之前做的东西

但是,这并没有给出正确的答案。正确答案是29,而我得到33。为什么会这样?

1 个答案:

答案 0 :(得分:3)

  

我认为这意味着x++++x之前完成。

不,这并不意味着。我previously blogged关于如何在执行顺序方面找到查看优先级是有问题的。它可能在计算机科学严格的方面有效,但它最终会让人感到困惑。

我觉得很多更容易将其视为分组。同样,我认为将关联性视为优先级是最容易的,但对于具有相同优先级的运算符。评估顺序始终从左到右。

所以这个:

int b = --var1 + ++var1 + var1++;

被分组,就像它被写了一样:

int b = (--var1) + (++var1) + (var1++);

那等同于:

int b = ((--var1) + (++var1)) + (var1++);

(由于二进制+具有从左到右的关联性。)

然后有效:

int tmp1 = --var1;       // tmp1 = 9, var1 = 9
int tmp2 = ++var1;       // tmp2 = 10, var1 = 10
int tmp3 = tmp1 + tmp2;  // tmp3 = 19
int tmp4 = var1++;       // tmp4 = 10, var1 = 11
int tmp5 = tmp3 + tmp4;  // tmp5 = 29

int b = tmp5;            // b = 29

......这证实了你所观察到的。

当然,你应该始终尽量避免让代码像这样复杂......

要演示评估顺序部分,请考虑以下表达式:

int result = a() + b() * c();

优先级意味着分组为:

int result = a() + (b() * c());

相当于:

// Evaluate LHS of +, which is just a()
int tmp1 = a();

// Evaluate RHS of +, which is b() * c()
// First evaluate LHS of *, which is b()
int tmp2 = b(); 
// Next evaluate RHS of *, which is c()
int tmp3 = c();
// Now we can evaluate *:
int tmp4 = tmp2 * tmp3;

// Now we can evaluate +:
result = tmp1 + tmp4;

当我们正在执行方法时,我们可以非常轻松地观察执行顺序:

public class Test {
    public static void main(String[] args) throws Exception {
        int result = a() + b() * c();
    }

    public static int a() {
        System.out.println("a()");
        return 3;
    }

    public static int b() {
        System.out.println("b()");
        return 4;
    }

    public static int c() {
        System.out.println("c()");
        return 5;
    }
}

打印:

a()
b()
c()

...确认我的扩展中显示的执行顺序。