【问题标题】:Java primitive variable reassignment during expression表达式期间的 Java 原始变量重新分配
【发布时间】:2020-12-21 02:48:14
【问题描述】:

我在测试中遇到了一个令我感到困惑的问题(代码附在下面)。简而言之,我认为变量被重新分配,然后作为一个值添加回表达式(使输出为“8, 10”),但似乎原始值没有改变。我错过了什么?

附言抱歉,如果存在类似问题,我找不到(可能太明显了:P)。

class InitTest{
    public static void main(String[] args){
        int a = 10;
        int b = 20;
        a += (a = 4);
        b = b + (b = 5);
        System.out.println(a + ",  " + b);
    }
}

【问题讨论】:

  • 请不要编写这样的代码 - 正如您可能已经注意到的那样,遵循它实际在做什么会令人困惑。
  • @Taschi:像这样的糟糕代码可能是编程认证考试的基石
  • @HovercraftFullOfEels,我不是经过认证的 Java 开发人员,但如果认证考试真的教会人们依赖边缘案例,那么更需要指出的是,这不是好的代码。跨度>
  • @Taschi-corporationsarebad 这不是我的代码????这是一个例子,我必须选择一个答案。

标签: java variable-assignment expression-evaluation


【解决方案1】:
a += (a = 4);

以上在逻辑上等价于以下:

a = a + (a = 4);

如果我们用现有值替换a,则简化为:

a = 10 + 4 = 14

我们可以为b做同样的事情:

b = b + (b = 5) = 20 + 5 = 25

我们看到这个结果是因为运算符优先级。加法运算符+ 的优先级高于赋值运算符=,由Java operator precedence table 定义。

您可以看到,加法赋值运算符+= 与赋值运算符具有相同的优先级,在这种情况下,表达式的计算顺序是从左到右。


如果相反,表达式是:

a = (a = 4) + a;
b = (b = 5) + b;

然后它将产生您期望的输出(a = 8b = 10),因为左操作数在右操作数之前计算(在计算表达式时)。我将尝试找到 Java 语言规范中指定的位置。

【讨论】:

  • 哦,我现在明白了。我的错误是我假设该值会动态变化
  • 表达式根据运算符优先级进行评估。从左到右计算的是 操作数。 OP 的结果是由于运算符优先级。
  • @JacobG.So 在这种情况下括号不算算术,而只是作为分配的分隔符? (我认为括号有更高的OP)
  • @ArturShalimov 有关括号在表达式评估中的作用的更多信息,我会在这里查看:If parenthesis has a higher precedence then why is increment operator solved first?
【解决方案2】:

在Java中,当给变量赋值时,首先计算的是=符号的左边部分,然后是右边部分。因此,当您编写 a += (a = 4); 时,它等同于 a = a + (a=4) ,它与 a = a + 4 相同,对于 b 也是如此。

【讨论】:

  • 为什么 = 符号的左边部分会被“计算”?它只是一个标识符。你不能给a + 5分配东西。
  • @Taschi-corporationsarebad 左侧必须解析为变量,可能是对象的字段或数组组件;例如,getObj().getArray()[4] = 5 显然要调用两个方法。在评估右侧之前评估左侧。
  • @kaya3,很公平,但评估不等于计算。我的a + 5 示例不是分配的有效左侧。
  • 计算是否是“计算”在技术意义上并没有真正定义。但如果它必须对数字进行算术运算才能算作计算,那么foo(a + 5).bar = "baz"; 应该符合您的标准。
猜你喜欢
  • 1970-01-01
  • 2022-10-12
  • 1970-01-01
  • 2017-09-13
  • 1970-01-01
  • 2013-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多