Java中的三元运算符自Java 7开始只评估一个表达式 - 在Java 1.6及以下版本中是否有所不同?

111

在准备Oracle Certified Associate Java SE 8程序员1考试时,我看到了官方学习指南中有关三元表达式的以下段落:

三元表达式的评估
从Java 7开始,在运行时只会评估三元运算符右边的一个表达式。类似于短路运算符,如果三元运算符的两个右侧表达式之一执行了副作用,则在运行时可能不会应用其中一个表达式。让我们通过以下示例来说明这个原则: [...]

这段话说只有两个表达式中的一个被评估,并用以下示例进行了演示。

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

这里,只有y递增,但z没有,这与您的期望不同。

我遇到的问题是段落开头的部分(用黄色标出),其中写道"As of Java 7, ..."。我使用Java 1.6测试了相同的代码,但行为没有任何区别。根据段落中的信息,我本来期望Java 1.6会对两个表达式都求值。是否有人知道他们在"As of Java 7,..."中想要表达什么意思?

编辑:为了避免混淆:问题归结为,既然他们写道“从Java 7开始”,那么在从Java 6切换到Java 7时,三元运算符是否有任何更改?


4
你为什么期望z也会增加?这对我来说没有任何意义。 - Jiří Kantor
15
听起来像是一本写得很差的书,三元运算符自 Java 诞生以来并没有改变,据我所知。 - NimChimpsky
23
迄今为止,阅读了大多数发布的答案后,人们似乎误解了问题。问题不是“为什么两个表达式都没有被评估?”,而是“为什么这本书似乎暗示它以前的行为方式不同?” - BambooleanLogic
24
实际上,“截至日期/版本X”通常表示“我们在日期/版本X上检查过这是正确的,但我们不会对之前的版本做出任何陈述。” 我猜这可能是此处的含义。(虽然您可能认为检查Java的早期版本很容易。)无论如何,这更多是英语问题而不是编程问题。 - David Z
14
@DavidZ: 当英语问题阻止你完成工作时,它们就成为编程问题。这个措辞不当的评论让原帖作者停下手头的工作,浪费时间却发现什么也没有改变。编程是沟通的过程,既要与编译器/解释器进行沟通,也要与维护代码的人进行沟通。我无数次读代码时因为某些奇怪的东西而停下来,只是因为它们被表达得很差劲,而事实上并没有真正的问题。 - jmoreno
显示剩余10条评论
2个回答

119

来自Java 6 JLS的条件表达式

运行时,先评估条件表达式的第一个操作数表达式;如果必要,对结果执行解包转换;然后使用生成的布尔值来选择第二个或第三个操作数表达式:

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

然后评估所选操作数表达式,并将生成的值转换为由上述规则确定的条件表达式类型。此转换可能包括装箱(§5.1.7)或解箱转换。未选择的操作数表达式在该条件表达式的特定评估中不会被评估。

类似的措辞也出现在1.0版及以后的JLS版本中。这种行为在Java 7中没有改变;参考指南只是用词不当。


2
那么答案是“在Java 7及之前,三元运算符没有任何区别”,对吗? - Mathias Bader
5
看起来合理。我给作者写了备忘录,期待他们的回复。 - Mathias Bader
如果你很谨慎或者好奇的话,你也可以找到一个比较不同版本之间操作符代码的URL。 - Steve Clay
8
每次参加 Oracle 认证考试时,糟糕的(或者完全错误的)问题数量令人惊讶。 - Voo

95

我是这本书的作者之一。虽然我没有写那个句子,但我同意其意图是“这已经在Java 7上进行了测试。”如果我们写另一版书,我会记下删除该句子。

需要明确的是,三元运算符在Java 8、7、6等版本中的行为方式都是相同的。而且如果未来行为发生更改,我会感到非常惊讶。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接