Operator trójskładnikowy w Javie oceniający tylko jedno wyrażenie od czasu Java 7 - czy było inaczej w Javie 1.6 i niższych?

109

Przygotowując się do egzaminu Oracle Certified Associate Java SE 8 Programmer 1, natknąłem się na następujący akapit dotyczący wyrażenia trójskładnikowego w oficjalnym Przewodniku po studiach:

Ocena wyrażenia trójskładnikowego
Począwszy od języka Java 7, tylko jedno z prawostronnych wyrażeń operatora trójskładnikowego zostanie ocenione w czasie wykonywania. Podobnie jak w przypadku operatorów zwarciowych, jeśli jedno z dwóch prawostronnych wyrażeń w operatorze trójskładnikowym wywołuje efekt uboczny, to nie może być stosowane w czasie wykonywania. Zilustrujmy tę zasadę następującym przykładem: [...]

Mówi, że oceniane jest tylko jedno z dwóch wyrażeń, co ilustruje następujący przykład:

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

Tutaj tylko yzwiększa, ale znie, jak można by się spodziewać.

To, na co się natknę, to początek akapitu (zaznaczony na żółto), w którym jest napisane „Od Java 7, ...”. Testowałem ten sam kod w Javie 1.6 i nie mogę znaleźć różnicy w zachowaniu. Spodziewałem się, że Java 1.6 oceni oba wyrażenia tylko na podstawie informacji podanych w akapicie. Czy ktoś ma pomysł, co chciałby powiedzieć „Od wersji Java 7…”?

Edycja: Aby uniknąć nieporozumień: sprowadza się do pytania, skoro piszą „od Java 7”, czy coś się zmieniło w odniesieniu do operatora trójskładnikowego podczas przełączania z Java 6 na Java 7?

Mathias Bader
źródło
4
Dlaczego miałbyś oczekiwać, że z również zostanie zwiększone? To nie ma dla mnie żadnego sensu.
Jiří Kantor
15
brzmi jak źle napisane książki, potrójne operatorzy nie uległy zmianie od czasu beginging java, AFAIK
Nim Chimpsky
23
Czytając większość dotychczas zamieszczonych odpowiedzi, ludzie wydają się błędnie interpretować pytanie. To nie jest „Dlaczego nie są oceniane oba wyrażenia?”, Ale raczej „Dlaczego ta książka wydaje się sugerować, że zachowywała się inaczej?”
BambooleanLogic
23
Właściwie widziałem, że „na dzień / wersję X” oznaczało „Sprawdziliśmy, czy to prawda w dniu / w wersji X, ale nie mówimy nic o wcześniejszych wersjach”. Zgaduję, że może to mieć tutaj znaczenie. (Chociaż można by pomyśleć, że łatwo byłoby sprawdzić wcześniejsze wersje Javy). W każdym razie jest to bardziej kwestia języka angielskiego niż programowania.
David Z
14
@DavidZ: Kwestie związane z językiem angielskim są problemami programistycznymi, kiedy uniemożliwiają wykonanie pracy. Ten słabo sformułowany komentarz sprawił, że OP przestał robić to, co robił i stracił czas na odkrywanie, że NIC SIĘ NIE ZMIENIŁO. Programowanie to komunikacja z kompilatorem / interpreterem i kimkolwiek, kto przyjdzie później, aby utrzymać kod. Nie mogę zliczyć czasów, kiedy czytałem jakiś kod i musiałem przestać z powodu czegoś dziwnego, co / mogło / mogło mieć coś wspólnego z problemem, tylko po to, by dowiedzieć się, że był on po prostu źle „sformułowany”.
jmoreno,

Odpowiedzi:

92

Jestem jednym z autorów książki, z której pochodzi. Chociaż nie napisałem tego konkretnego zdania, zgadzam się, że intencją było „to zostało przetestowane na Javie 7”. Zanotuję to, aby to usunąć, jeśli napiszemy kolejne wydanie.

Żeby było jasne, operator trójskładnikowy zachował się w ten sam sposób w Javie 8, 7, 6 itd. Byłbym bardzo zaskoczony, gdyby zmienił się w przyszłości.

Jeanne Boyarsky
źródło
116

Z JLS Java 6 :

W czasie wykonywania pierwsze wyrażenie operandowe wyrażenia warunkowego jest oceniane jako pierwsze; w razie potrzeby na wyniku przeprowadzana jest konwersja rozpakowania; wynikowa wartość logiczna jest następnie używana do wyboru drugiego lub trzeciego wyrażenia operandu:

  • Jeśli wartość pierwszego operandu jest prawdziwa, wybierane jest drugie wyrażenie operandu.
  • Jeśli wartością pierwszego operandu jest fałsz, wybierane jest trzecie wyrażenie operandu.

Wybrane wyrażenie operandu jest następnie oceniane, a wynikowa wartość jest konwertowana na typ wyrażenia warunkowego zgodnie z powyższymi regułami. Ta konwersja może obejmować konwersję typu boxing (§5.1.7) lub unboxing. Niewybrane wyrażenie operandu nie jest oceniane dla tej konkretnej oceny wyrażenia warunkowego.

Podobne sformułowanie pojawia się również w wydaniach JLS sięgających 1.0 . Zachowanie nie zmieniło się w Javie 7; podręcznik do nauki jest po prostu źle sformułowany.

user2357112 obsługuje Monikę
źródło
2
Tak więc odpowiedź brzmi: „Nie ma różnicy od wersji Java 7 i wcześniej, jeśli chodzi o operator trójskładnikowy”, prawda?
Mathias Bader
5
Wydaje się uzasadnione. Napisałem notatkę do autorów - nie mogę się doczekać odpowiedzi
Mathias Bader
Prawdopodobnie możesz również znaleźć adres URL, który porównuje kod operatora między wersjami. Jeśli jesteś paranoikiem / jesteś ciekawy.
Steve Clay,
7
Liczba źle napisanych (lub po prostu źle sformułowanych) pytań w tych certyfikatach Oracle jest zadziwiająca za każdym razem.
Voo