从Java 7开始,Java中的三元运算符仅评估一个表达式-Java 1.6和更低版本中的表达式不同吗?


109

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

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

它说仅对两个表达式之一进行求值,并通过以下示例进行演示:

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

在这里,仅y增加,但z没有增加,正如您期望的那样。

我遇到的是该段落的开头(以黄色标记),该段落的内容为“从Java 7开始,...”。我使用Java 1.6测试了相同的代码,但在行为上没有发现差异。我希望Java 1.6仅根据本段给出的信息来评估这两个表达式。有谁知道他们想对“从Java 7开始...”说什么?

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


4
为什么还要期望z也增加?这对我来说毫无意义。
吉日坎特

15
听起来像是一本写得不好的书,自Java afaik
诞生

23
阅读到目前为止发布的大多数答案,人们似乎对这个问题有误解。不是“为什么不对两个表达式都求值?”而是“为什么这本书似乎暗示它过去表现的不同?”
BambooleanLogic

23
实际上,我已经看到“截止日期X版本”曾经表示“我们检查日期X版本中的情况是正确的,但我们没有说任何有关早期版本的信息。” 我猜这可能是这里的意思。(尽管您认为检查Java的早期版本会很容易。)无论如何,与编程相比,这更多的是英语问题。
大卫Z

14
@DavidZ:当英语问题使您无法完成工作时,它们就是编程问题。措辞不佳的评论使OP停止了他正在做的事情,并浪费了时间,发现“一切都没有改变”。编程就是与编译器/解释器以及以后维护代码的人员进行通信。我无法数出我一直在阅读一些代码的时间,并且不得不停止因为/ might /与该问题有关的某些奇怪事情,而只是发现它被严重“措辞”了。
jmoreno 2015年

Answers:


92

我是这本书的作者之一。虽然我没有写这句话,但我同意其意图是“这已在Java 7上进行了测试”。如果我们要写另一个版本,我会做个注释以消除它。

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


116

Java 6 JLS

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

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

然后评估所选的操作数表达式,并将结果值转换为条件表达式的类型,该条件表达式由上述规则确定。此转换可能包括装箱(第5.1.7节)或拆箱转换。对于条件表达式的特定评估,不会评估未选择的操作数表达式。

早于1.0的 JLS版本中也出现了类似的措辞。在Java 7中,行为没有改变。学习指南措辞不佳。


2
因此答案是“与Java 7相比,与三元运算符没有任何区别”,对吗?
Mathias Bader

5
似乎是合法的。我给作者写了一封备忘录-期待他们的回答
Mathias Bader

您也可能会找到一个URL,该URL在两个版本之间比较运算符的代码。如果您偏执/好奇。
史蒂夫·克莱

7
在这些甲骨文认证写的不好(或只是平了错误)问题的数字是..再次惊人的每一次
VOO
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.