自 Java 7 以来,Java 中的三元运算符仅计算一个表达式 - 这在 Java 1.6 及更低版本中是否有所不同?

在准备Oracle认证助理Java SE 8程序员1考试时,我在官方学习指南中遇到了以下关于三元表达式的段落:

三元表达式计算
从 Java 7 开始,在运行时只计算三元运算符的右置表达式之一。与短路运算符类似,如果三元运算符中的两个右侧表达式之一执行副作用,则可能无法在运行时应用它。让我们用下面的例子来说明这个原则:[...]

它说只计算了两个表达式中的一个,并通过以下示例进行演示:

int y = 1;
int z = 1;
int a = y < 10 ? y++ : z++;

在这里,只有增量,但不会,正如您所期望的那样。yz

我偶然发现的是段落的开头(用黄色标记),上面写着“截至Java 7,...”。我用Java 1.6测试了相同的代码,但我找不到行为上的区别。我期望Java 1.6仅根据段落中提供的信息来计算这两个表达式。有没有人知道他们想用“截至Java 7,...”说些什么?

编辑:为了避免混淆:它归结为一个问题,既然他们写了“从Java 7开始”,那么从Java 6切换到Java 7时,三元运算符有什么变化吗?


答案 1

来自 Java 6 JLS

在运行时,首先计算条件表达式的第一个操作数表达式;如有必要,对结果执行拆箱转换;然后,使用生成的布尔值来选择第二个或第三个操作数表达式:

  • 如果第一个操作数的值为 true,则选择第二个操作数表达式。
  • 如果第一个操作数的值为 false,则选择第三个操作数表达式。

然后计算所选的操作数表达式,并将结果值转换为由上述规则确定的条件表达式的类型。此转换可能包括装箱 (§5.1.7) 或取消装箱转换。未选择的操作数表达式不会针对条件表达式的特定计算进行计算。

类似的措辞也出现在JLS版本中,可以追溯到1.0。在Java 7中,行为没有改变。学习指南只是措辞不当。


答案 2

我是这本书的作者之一。虽然我没有写那个特定的句子,但我同意其意图是“这是在Java 7上测试的”。如果我们写另一个版本,我会做一个注释来删除它。

需要明确的是,三元运算符在Java 8,7,6等中的行为方式相同。如果它在未来发生变化,我会感到非常惊讶。