Тернарный оператор в Java, начиная с Java 7, оценивает только одно выражение - отличалось ли это в Java 1.6 и ниже?

109

Готовясь к экзамену Oracle Certified Associate Java SE 8 Programmer 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
NimChimpsky
23
Читая большинство ответов, опубликованных на данный момент, люди, похоже, неверно истолковывают вопрос. Это не «Почему не оцениваются оба выражения?», А скорее «Почему эта книга, по-видимому, подразумевает, что раньше она вела себя по-разному?»
BambooleanLogic
23
На самом деле, я видел, что «По состоянию на дату / версию X» означает «Мы проверили, что это правда на дату / в версии X, но мы ничего не говорим о более ранних версиях». Я предполагаю, что здесь может быть смысл. (Хотя вы могли бы подумать, что будет достаточно легко проверить более ранние версии Java.) В любом случае, это скорее вопрос английского, чем программирования.
Дэвид З
14
@DavidZ: Проблемы с английским - это проблемы с программированием, когда они мешают вам выполнять свою работу. Этот плохо сформулированный комментарий заставил ОП прекратить то, что он делал, и зря потратить время на обнаружение, что НИЧЕГО НЕ ИЗМЕНИЛОСЬ. Программирование - это общение с компилятором / интерпретатором и со всеми, кто позже придет, чтобы поддерживать ваш код. Я не могу сосчитать, сколько раз я читал какой-то код, и мне приходилось останавливаться из-за чего-то странного, что / могло / иметь какое-то отношение к проблеме, только чтобы узнать, что это было просто плохо "сформулировано".
jmoreno

Ответы:

92

Я один из авторов этой книги. Хотя я не писал это конкретное предложение, я согласен, что целью было «это было протестировано на Java 7». Сделаю пометку, чтобы убрать это, если мы напишем другое издание.

Чтобы было ясно, тернарный оператор ведет себя таким же образом в Java 8, 7, 6 и т. Д. И я был бы очень удивлен, если бы он изменился в будущем.

Жанна Боярская
источник
116

Из Java 6 JLS :

Во время выполнения сначала вычисляется первое выражение операнда условного выражения; при необходимости по результату выполняется распаковка конвертации; полученное логическое значение затем используется для выбора второго или третьего выражения операнда:

  • Если значение первого операнда истинно, то выбирается выражение второго операнда.
  • Если значение первого операнда ложно, то выбирается третье выражение операнда.

Выбранное выражение операнда затем оценивается, и результирующее значение преобразуется в тип условного выражения в соответствии с указанными выше правилами. Это преобразование может включать преобразование упаковки (§5.1.7) или распаковки. Невыбранное выражение операнда не оценивается для этой конкретной оценки условного выражения.

Аналогичная формулировка также появляется в редакциях JLS, начиная с версии 1.0 . В Java 7 поведение не изменилось; Учебное пособие просто плохо сформулировано.

user2357112 поддерживает Монику
источник
2
Итак, ответ: «В Java 7 и ранее нет разницы в отношении тернарного оператора», верно?
Матиас Бадер
5
Выглядит вполне законно. Я написал меморандум авторам - с нетерпением жду их ответа
Матиас Бадер
Вы также, вероятно, можете найти URL-адрес, который сравнивает код оператора между версиями. Если вы параноик / любопытный.
Стив Клэй,
7
Количество плохо написанных (или просто совершенно неверных) вопросов в этих сертификатах Oracle каждый раз поражает снова ..
Voo