java中的一元运算符优先级

Ima*_*kin 2 java operators

现在,根据网站,一元后自增一元前自增具有更高的优先级。我想这意味着,那x++是之前完成的++x

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

int var1=10; 
int b= --var1 + ++var1 + var1++;
Run Code Online (Sandbox Code Playgroud)

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

b = --var1 + ++var1 + 10   
Run Code Online (Sandbox Code Playgroud)

现在,如果我认为它应该++var1在之前执行--var1,因为它提到关联性是从右到左。我想,这意味着先做右边的事,再做左边的事

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

Jon*_*eet 6

我想这意味着,那x++是之前完成的++x

不,不是这个意思。我之前曾在博客中介绍过我如何发现执行顺序方面的查看优先级是有问题的。从严格的计算机科学角度来看,它很可能是有效的,但最终却让人们感到困惑。

我发现将其视为分组更容易。同样,我认为最容易将结合性视为优先级,但对于优先级相同的运算符而言。评估顺序始终是从左到右。

所以这:

int b = --var1 + ++var1 + var1++;
Run Code Online (Sandbox Code Playgroud)

被分组就好像它被写成:

int b = (--var1) + (++var1) + (var1++);
Run Code Online (Sandbox Code Playgroud)

那么这相当于:

int b = ((--var1) + (++var1)) + (var1++);
Run Code Online (Sandbox Code Playgroud)

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

那么这实际上是:

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
Run Code Online (Sandbox Code Playgroud)

...这证实了您所观察到的情况。

当然,您应该始终尽量避免使用像这样复杂的代码......

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

int result = a() + b() * c();
Run Code Online (Sandbox Code Playgroud)

优先级意味着分组为:

int result = a() + (b() * c());
Run Code Online (Sandbox Code Playgroud)

这相当于:

// 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;
Run Code Online (Sandbox Code Playgroud)

当我们执行方法时,我们可以很容易地观察到执行顺序:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

打印:

a()
b()
c()
Run Code Online (Sandbox Code Playgroud)

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

  • @Shashwat:让我们更简单地推理一下:如果你有“a + b * c”,则评估“a”,然后评估“b * c”。要评估“b * c”,首先评估“b”,然后评估“c”。通过将其设置为“a() + b() * c()”,您可以很容易地看到这一点,其中每个方法都会打印出它正在执行。 (3认同)