繁体   English   中英

Java 表达顺序、运算符优先级和结合性之间的差异

[英]Differences between Java order of expression, operator precedence and associativity

我在考试中遇到了这个问题。

考试题:以下代码片段的结果是什么?

3: var tiger = "Tiger";
4: var lion = "Lion";
5: final var statement = 250 > 338 ? lion : tiger = " is Bigger";
6: System.out.println(statement);

正确答案是

F. 由于第 5 行,代码将无法编译

解释是:

  1. 代码无法编译,因为赋值运算符在此表达式中具有最高优先级。
  2. 三元运算符的两边必须具有相同的类型。 这个表达式无效,因为第二个赋值运算符的左边不是变量,所以答案是选项 F。
  3. 请注意,如果问题在表达式周围添加了显式括号(Tiger = " is Bigger"),则选项 E 将具有正确的 output。

当我自己运行代码时,出现编译错误:

test.java:11: error: unexpected type
final var statement = 250 > 338 ? lion : tiger = " is Bigger";
                                ^
  required: variable
  found:    value
1 error
error: compilation failed

在征求第二意见后,阅读 JLS 第15节,以及这些其他 SO 问题:

Java中评估顺序的规则是什么?

如果括号具有更高的优先级,那么为什么首先解决增量运算符?

我提出了几个理论:

  1. 表达式求值顺序、运算符优先级和关联性是不同的概念。
  2. 根据 JLS 15.7.3,表达式评估尊重括号和运算符优先级。
  3. 所有表达式评估都是从左到右进行的。
  4. 运算符优先级决定了表达式的分组。
  5. 关联性仅适用于同一运算符,并确定使用同一运算符的表达式的执行顺序。
  6. Java 在编译时检查有效表达式,从左到右,尊重括号和运算符优先级。
  7. 对于带有运算符的表达式,它会根据运算符以不同的方式对操作数执行此检查。

有了新知识,我现在将尝试解释为什么第 5 行无法编译:

  1. Java 使用表达式评估顺序从左到右开始检查有效表达式。
  2. Java 找到第一个赋值运算符(最左边)。
  3. 由于赋值运算符“=”具有从右到左的关联性,因此 Java 检查右侧是否还有其他赋值运算符,并开始计算更右的赋值运算符。
  4. 它找到一个“=”,然后检查右侧的任何其他“=”。
  5. 我没有找到其他“=”,所以它开始评估这个最右边“=”的操作数。
  6. 根据 15.26,Java 检查前一个“=”和这个“=”之间的所有内容是否只是一个变量。
  7. 它找到表达式250 > 338? lion: tiger 250 > 338? lion: tiger ,这是一个有效的表达式,但这个表达式的计算结果是一个值。
  8. Java 只允许赋值运算符左侧的变量,所以编译失败。

现在我会尝试应用同样的理论来解释这段代码的正确场景: final var statement = 250 > 338? lion: (tiger = " is Bigger"); final var statement = 250 > 338? lion: (tiger = " is Bigger");

  1. Java 使用表达式评估顺序从左到右开始检查有效表达式。
  2. Java 在同一个“作用域”中没有找到任何其他赋值运算符“=”。
  3. 根据 15.26,Java 检查此“=”的左操作数是否为变量。 通过。
  4. 然后它评估右操作数是否是返回可分配给左操作数的值的有效表达式。

考试提供的解释是否落空了,还是我仍然不明白这段代码是如何编译的?

  1. 他们说赋值运算符“=”在这个表达式中具有最高优先级。 根据此运算符优先级表http://www.cs.bilkent.edu.tr/~guvenir/courses/CS101/op_precedence.html ,赋值运算符的优先级最低。
  2. 他们将运算符优先级与评估表达式的顺序互换使用,而不是将这两个概念分开?

你是对的,他们说错了,赋值运算符的优先级最低

你是不正确的,他们从来没有在任何地方提到“评估顺序”(无论如何你已经展示过)。 显示的代码在评估顺序很重要的地方没有做任何事情。 作业与评估顺序无关。



  1. 代码无法编译,因为赋值运算符在此表达式中具有最高优先级。

运算符优先级显示:

9   >   relational
2   ?:  ternary
1   =   assignment

这意味着要使用括号显式显示优先级,语句变为:

statement = ((250 > 338) ? lion : tiger) = " is Bigger";

  1. 三元运算符的两边必须具有相同的类型。 这个表达式无效,因为第二个赋值运算符的左边不是变量,所以答案是选项 F。

三元运算符是((250 > 338)? lion: tiger) ,“双方”指的是两个赋值运算符。

正如它所说,“这个表达式无效,因为第二个赋值运算符的左侧不是变量”。


  1. 请注意,如果问题在表达式周围添加了显式括号(Tiger = " is Bigger"),则选项 E 将具有正确的 output。

你自己已经确认过了。

要使用括号显式显示优先级,语句变为:

statement = ( (250 > 338) ? lion : (tiger = " is Bigger") );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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