Ternärer Operator in Java wertet seit Java 7 nur einen Ausdruck aus - war das in Java 1.6 und niedriger anders?

109

Als ich mich auf die Prüfung zum Oracle Certified Associate Java SE 8-Programmierer 1 vorbereitete, stieß ich im offiziellen Studienhandbuch auf den folgenden Absatz über den ternären Ausdruck:

Auswertung
ternärer Ausdrücke Ab Java 7 wird zur Laufzeit nur einer der rechten Ausdrücke des ternären Operators ausgewertet. In ähnlicher Weise wie bei den Kurzschlussoperatoren wird einer der beiden rechten Ausdrücke in einem ternären Operator möglicherweise nicht zur Laufzeit angewendet, wenn er einen Nebeneffekt ausführt. Lassen Sie uns dieses Prinzip anhand des folgenden Beispiels veranschaulichen: [...]

Es heißt, dass nur einer der beiden Ausdrücke ausgewertet wird, was anhand des folgenden Beispiels demonstriert wird:

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

Hier nur yinkrementiert, aber znicht, wie Sie es erwarten würden.

Ich stolpere über den Anfang des Absatzes (gelb markiert) mit der Aufschrift "Ab Java 7, ...". Ich habe den gleichen Code mit Java 1.6 getestet und kann keinen Unterschied im Verhalten feststellen. Ich habe erwartet, dass Java 1.6 beide Ausdrücke nur anhand der im Absatz angegebenen Informationen bewertet. Hat jemand eine Idee, was er mit "Ab Java 7, ..." sagen wollte?

Bearbeiten: Um Verwirrung zu vermeiden: Es läuft auf die Frage hinaus: Hat sich beim Wechsel von Java 6 zu Java 7 etwas geändert, da sie "Ab Java 7" schreiben?

Mathias Bader
quelle
4
Warum würden Sie erwarten, dass z auch erhöht wird? Das ergibt für mich keinen Sinn.
Jiří Kantor
15
klingt wie ein schlecht geschriebenes Buch, ternäre Operatoren haben sich seit dem Beginn von Java, afaik
NimChimpsky
23
Wenn man die meisten der bisher veröffentlichten Antworten liest, scheint man die Frage falsch zu interpretieren. Es ist nicht "Warum werden nicht beide Ausdrücke bewertet?", Sondern "Warum impliziert dieses Buch anscheinend, dass es sich früher anders verhalten hat?"
BambooleanLogic
23
Eigentlich habe ich gesehen, dass "Ab Datum / Version X" bedeutet "Wir haben überprüft, ob dies am Datum / in Version X zutrifft, aber wir sagen nichts über frühere Versionen." Ich vermute, das könnte hier die Bedeutung sein. (Obwohl Sie denken würden, dass es einfach genug wäre, frühere Versionen von Java zu überprüfen.) Wie auch immer, das ist eher ein englisches Problem als ein Programmierproblem.
David Z
14
@DavidZ: Englischprobleme sind Programmierprobleme, wenn sie Sie daran hindern, Ihre Arbeit zu erledigen. Dieser schlecht formulierte Kommentar ließ das OP aufhören, was er tat, und Zeit damit verschwenden, herauszufinden, dass sich NICHTS GEÄNDERT hat. Programmierung ist Kommunikation mit dem Compiler / Interpreter und jedem, der später kommt, um Ihren Code zu pflegen. Ich kann die Zeiten nicht zählen, in denen ich Code gelesen habe und wegen etwas Seltsamem aufhören musste, das / könnte / etwas mit dem Problem zu tun haben könnte, nur um herauszufinden, dass es nur schlecht "formuliert" war.
jmoreno

Antworten:

92

Ich bin einer der Autoren des Buches, aus dem dies stammt. Obwohl ich diesen bestimmten Satz nicht geschrieben habe, stimme ich zu, dass die Absicht darin bestand, "dies wurde auf Java 7 getestet". Ich werde eine Notiz machen, um das zu entfernen, wenn wir eine andere Ausgabe schreiben.

Um es klar auszudrücken, hat sich der ternäre Operator in Java 8, 7, 6 usw. genauso verhalten. Und ich wäre ziemlich überrascht, wenn er sich in Zukunft ändern würde.

Jeanne Boyarsky
quelle
116

Aus dem Java 6 JLS :

Zur Laufzeit wird zuerst der erste Operandenausdruck des bedingten Ausdrucks ausgewertet; Falls erforderlich, wird eine Unboxing-Konvertierung für das Ergebnis durchgeführt. Der resultierende boolesche Wert wird dann verwendet, um entweder den zweiten oder den dritten Operandenausdruck auszuwählen:

  • Wenn der Wert des ersten Operanden wahr ist, wird der zweite Operandenausdruck ausgewählt.
  • Wenn der Wert des ersten Operanden falsch ist, wird der dritte Operandenausdruck ausgewählt.

Der ausgewählte Operandenausdruck wird dann ausgewertet und der resultierende Wert wird in den Typ des bedingten Ausdrucks konvertiert, wie durch die oben angegebenen Regeln bestimmt. Diese Konvertierung kann Boxing (§5.1.7) oder Unboxing-Konvertierung umfassen. Der nicht ausgewählte Operandenausdruck wird für diese bestimmte Bewertung des bedingten Ausdrucks nicht ausgewertet.

Ein ähnlicher Wortlaut erscheint auch in JLS-Editionen, die auf 1.0 zurückgehen . Das Verhalten hat sich in Java 7 nicht geändert. Der Studienführer ist nur schlecht formuliert.

user2357112 unterstützt Monica
quelle
2
Die Antwort lautet also "Ab Java 7 und früher gibt es keinen Unterschied bezüglich des ternären Operators", oder?
Mathias Bader
5
Klingt plausibel. Ich schrieb ein Memo an die Autoren - ich freue mich auf ihre Antwort
Mathias Bader
Möglicherweise finden Sie auch eine URL, die den Code des Operators zwischen den Versionen vergleicht. Wenn Sie paranoid / neugierig sind.
Steve Clay
7
Die Anzahl der schlecht geschriebenen (oder einfach nur falschen) Fragen in diesen Oracle-Zertifizierungen ist jedes Mal wieder erstaunlich.
Voo