Opérateur ternaire en Java évaluant une seule expression depuis Java 7 - était-ce différent dans Java 1.6 et les versions antérieures?

109

En me préparant à l'examen Oracle Certified Associate Java SE 8 Programmer 1, je suis tombé sur le paragraphe suivant sur l'expression ternaire dans le guide d'étude officiel:

Évaluation des expressions ternaires
À partir de Java 7, une seule des expressions de droite de l'opérateur ternaire sera évaluée lors de l'exécution. D'une manière similaire aux opérateurs de court-circuit, si l'une des deux expressions de droite dans un opérateur ternaire produit un effet secondaire, alors il peut ne pas être appliqué au moment de l'exécution. Illustrons ce principe avec l'exemple suivant: [...]

Il dit qu'une seule des deux expressions est évaluée, ce qui montre l'exemple suivant:

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

Ici, seulement yincrémente, mais zpas, comme vous vous en doutez.

Ce que je suis en train de trébucher, c'est le début du paragraphe (marqué en jaune) où il est dit "À partir de Java 7, ...". J'ai testé le même code avec Java 1.6 et je ne trouve pas de différence dans le comportement. Je m'attendais à ce que Java 1.6 évalue les deux expressions uniquement à partir des informations données dans le paragraphe. Quelqu'un a-t-il une idée de ce qu'il voulait dire avec "A partir de Java 7, ..."?

Edit: Pour éviter toute confusion: Cela se résume à la question, puisqu'ils écrivent «À partir de Java 7», y a-t-il eu quelque chose qui a changé concernant l'opérateur ternaire, lors du passage de Java 6 à Java 7?

Mathias Bader
la source
4
Pourquoi vous attendez-vous à ce que z augmente également? Cela n'a aucun sens pour moi.
Jiří Kantor
15
sonne comme un livre mal écrit, les opérateurs ternaires n'ont pas changé depuis le début de java, afaik
NimChimpsky
23
En lisant la plupart des réponses publiées jusqu'à présent, les gens semblent mal interpréter la question. Ce n'est pas "Pourquoi les deux expressions ne sont-elles pas évaluées?", Mais plutôt "Pourquoi ce livre semble-t-il impliquer qu'il se comportait différemment?"
BambooleanLogic
23
En fait, j'ai vu que «À la date / version X» signifiait «Nous avons vérifié que cela est vrai à la date / dans la version X mais nous ne disons rien des versions antérieures». Je suppose que c'est peut-être le sens ici. (Bien que vous pensiez qu'il serait assez facile de vérifier les versions antérieures de Java.) Quoi qu'il en soit, c'est plus un problème anglais qu'un problème de programmation.
David Z
14
@DavidZ: Les problèmes d'anglais sont des problèmes de programmation lorsqu'ils vous empêchent de faire votre travail. Ce commentaire mal formulé a obligé l'OP à arrêter ce qu'il faisait et à perdre du temps à découvrir que RIEN N'A CHANGÉ. La programmation est la communication, avec le compilateur / interpréteur et avec quiconque vient plus tard pour maintenir votre code. Je ne peux pas compter les fois où j'ai lu du code et j'ai dû m'arrêter à cause de quelque chose d'étrange qui / aurait pu / avoir quelque chose à voir avec le problème, seulement pour découvrir que c'était juste mal "formulé".
jmoreno

Réponses:

92

Je suis l'un des auteurs du livre dont cela vient. Bien que je n'ai pas écrit cette phrase particulière, je suis d'accord que l'intention était "ceci a été testé sur Java 7". Je ferai une note pour supprimer cela si nous écrivons une autre édition.

Pour être clair, l'opérateur ternaire s'est comporté de la même manière dans Java 8, 7, 6, etc. Et je serais assez surpris si cela changeait à l'avenir.

Jeanne Boyarsky
la source
116

À partir du JLS Java 6 :

Au moment de l'exécution, la première expression d'opérande de l'expression conditionnelle est évaluée en premier; si nécessaire, une conversion de déballage est effectuée sur le résultat; la valeur booléenne résultante est ensuite utilisée pour choisir la deuxième ou la troisième expression d'opérande:

  • Si la valeur du premier opérande est vraie, la deuxième expression d'opérande est choisie.
  • Si la valeur du premier opérande est fausse, la troisième expression d'opérande est choisie.

L'expression d'opérande choisie est ensuite évaluée et la valeur résultante est convertie dans le type de l'expression conditionnelle comme déterminé par les règles énoncées ci-dessus. Cette conversion peut inclure la conversion de boxe (§5.1.7) ou de déballage. L'expression d'opérande non choisie n'est pas évaluée pour cette évaluation particulière de l'expression conditionnelle.

Une formulation similaire apparaît également dans les éditions JLS remontant à 1.0 . Le comportement n'a pas changé dans Java 7; le guide d'étude est simplement mal rédigé.

user2357112 prend en charge Monica
la source
2
Donc la réponse est "Il n'y a aucune différence à partir de Java 7 et avant, concernant l'opérateur ternaire", non?
Mathias Bader
5
Semble légitime. J'ai écrit une note aux auteurs - dans l'attente de leur réponse
Mathias Bader
Vous pourriez aussi probablement trouver une URL qui compare le code de l'opérateur entre les versions. Si vous êtes paranoïaque / curieux.
Steve Clay
7
Le nombre de questions mal écrites (ou tout simplement fausses) dans ces certifications Oracle est à chaque fois étonnant.
Voo