Java表达式顺序,运算符优先级和关联性之间的差异

问题描述

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

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

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将具有正确的括号 输出。

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

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问题:

What are the rules for evaluation order in Java?

If parenthesis has a higher precedence then why is increment operator solved first?

我想出了一些理论:

  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,它是一个有效表达式,但是该表达式的值是一个值。
  8. Java仅允许赋值运算符左侧的变量,因此无法编译。

现在,我将尝试应用相同的理论来解释此代码的正确方案: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. 由于赋值运算符在此表达式中具有最高优先级,因此代码无法编译。

Operator precedence显示:

9   >   relational
2   ?:  ternary
1   =   assignment

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

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

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

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

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


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

您已经确认自己。

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

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

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...