189 votes

Comment s'appelle l'opérateur Java ? : et que fait-il ?

Je travaille avec Java depuis quelques années, mais jusqu'à récemment, je n'avais jamais rencontré cette construction :

int count = isHere ? getHereCount(index) : getAwayCount(index);

Il s'agit probablement d'une question très simple, mais quelqu'un peut-il l'expliquer ? Comment puis-je le lire ? Je suis pratiquement sûr de savoir comment il fonctionne.

  • si isHere est vrai, getHereCount() s'appelle,
  • si isHere est faux getAwayCount() s'appelle.

Correct ? Comment s'appelle cette construction ?

2 votes

Voir aussi stackoverflow.com/questions/795286/what-does-do-in-c pour la version C++ de cette question (posée hier, en fait).

2 votes

Gardez à l'esprit que le monde C/C++/Java est divisé de manière assez égale entre les personnes qui pensent que c'est laid et confus et qui l'éviteront comme la peste, et les personnes qui pensent que vous ne pouvez pas vraiment prétendre connaître C, C++ ou Java si vous ne pouvez pas le reconnaître et l'utiliser sans prendre le temps de réfléchir.

3 votes

En Java, il est généralement mal vu de l'utiliser en dehors des cas les plus clairs et les plus simples. Si vous vous retrouvez à les imbriquer, vous êtes loin du compte. En revanche, dans la culture C, où le code rapide et intelligent est plus apprécié que la clarté, il est considéré comme acceptable.

214voto

Michael Myers Points 82361

Oui, c'est une forme abrégée de

int count;
if (isHere)
    count = getHereCount(index);
else
    count = getAwayCount(index);

C'est ce qu'on appelle le opérateur conditionnel . Beaucoup de gens l'appellent (à tort) l'opérateur ternaire parce que c'est le seul opérateur ternaire (à trois arguments) en Java, C, C++ et probablement dans de nombreux autres langages. Mais théoriquement, il existe pourrait être un autre opérateur ternaire, alors qu'il ne peut y avoir qu'un seul opérateur conditionnel .

Le nom officiel est donné dans le Spécification du langage Java :

§15.25 Opérateur conditionnel ? :

L'opérateur conditionnel ? : utilise la valeur booléenne d'une expression pour décider laquelle des deux autres expressions doit être évaluée.

Notez que les deux branches doivent mener à des méthodes avec des valeurs de retour :

C'est une erreur de compilation si la deuxième ou la troisième expression opérande est une invocation d'une méthode void.

En fait, selon la grammaire des déclarations d'expression ( §14.8 ), il n'est pas permis qu'une expression conditionnelle apparaisse dans un contexte où l'invocation d'une méthode void pourrait apparaître.

Donc, si doSomething() y doSomethingElse() sont des méthodes nulles, vous ne pouvez pas les compresser :

if (someBool)
    doSomething();
else
    doSomethingElse();

dans ceci :

someBool ? doSomething() : doSomethingElse();

Des mots simples :

booleanCondition ? executeThisPartIfBooleanConditionIsTrue : executeThisPartIfBooleanConditionIsFalse

0 votes

Je ne comprends pas ce que fait le bas qui est mauvais. Je vous crois et tout. Il me semble juste que c'est le même que l'original. Est-ce parce qu'ils appellent simplement une autre fonction qui peut ou non retourner une valeur et permettre au prochain jeu de code de s'exécuter ?

8 votes

Je suppose que doSomething() et doSomethingElse() sont des méthodes void. Ce que dit la dernière partie de la spécification est que l'opérateur ternaire debe retournent une valeur, donc aucun des opérandes ne peut être une méthode void.

0 votes

Ça dit un peu plus que ça. Il dit que l'opérateur conditionnel n'est pas autorisé là où une méthode void POURRAIT apparaître. Donc, par exemple, les déclarations suivantes : VALIDE : Chaîne x = (false) ? "X" : "Y" ; NON VALIDE : (false) ? "X" : "Y" ;

33voto

Jon Skeet Points 692016

D'autres ont répondu à cette question dans une mesure raisonnable, mais souvent sous le nom d'"opérateur ternaire".

En tant que pédant, je tiens à préciser que le nom de l'opérateur est l'opérateur conditionnel ou "opérateur conditionnel ? :". Il s'agit de a opérateur ternaire (dans le sens où il a trois opérandes) et il se trouve être le seul opérateur ternaire en Java pour le moment.

Cependant, le La spécification est assez claire que son nom est l'opérateur conditionnel ou "opérateur conditionnel ? :" pour être absolument sans ambiguïté. Je pense qu'il est plus clair de l'appeler par ce nom, car il indique dans une certaine mesure le comportement de l'opérateur (évaluation d'une condition) plutôt que le nombre d'opérandes qu'il possède.

3 votes

Cette réponse est techniquement correcte. Cependant, comme il n'y a qu'un seul opérateur ternaire, on l'appelle souvent l'opérateur ternaire. Même si ce nom ne traduit pas la signification complète de l'opérateur, il s'agit d'un nom qui est resté. Si vous mentionnez le nom "opérateur ternaire", les programmeurs savent de quoi vous parlez. La spécification que vous mentionnez fait également référence à cet opérateur en tant que "conditionnel ternaire", ce qui semble plus informatif. java.sun.com/docs/books/jls/third_edition/html/

17 votes

Je pense juste que ça vaut la peine d'appeler quelque chose par son nom défini. En particulier, si Java se dote un jour d'un autre opérateur ternaire, les personnes qui utilisent le terme "opérateur conditionnel" seront toujours correctes et sans ambiguïté - contrairement à celles qui disent simplement "opérateur ternaire". Oui, l'expression "opérateur ternaire" est restée bloquée - ma réponse fait partie d'un effort pour la "décoller", tout comme j'essaie de corriger l'affirmation selon laquelle "les objets sont passés par référence".

1 votes

Puis-je vous diriger vers cette page de Oracle qui parle de trois "opérateurs conditionnels" mais d'un seul "opérateur ternaire" ? Si vous voulez indiquer clairement de quel opérateur vous parlez, il est probablement préférable d'utiliser le nom que la plupart des gens utilisent. (Oui, je sais que j'arrive à la fête au moment où l'hôte fait la dernière vaisselle).

17voto

JRL Points 36674

Selon le Spécification Sun Java c'est ce qu'on appelle l'opérateur conditionnel. Voir la section 15.25. Vous avez raison quant à sa fonction.

L'opérateur conditionnel ? : utilise la valeur booléenne d'une expression pour décider laquelle des deux autres expressions doit être évaluée.

L'opérateur conditionnel est syntaxiquement associatif à droite (il regroupe de droite à gauche), de sorte que a?b:c?d:e?f:g signifie la même chose que a?b :(c?d :(e?f:g)).

ConditionalExpression:
        ConditionalOrExpression
        ConditionalOrExpression ? Expression : ConditionalExpression

L'opérateur conditionnel a trois expressions opérandes ; ? apparaît entre la première et la deuxième expression, et : apparaît entre la deuxième et la troisième expression.

La première expression doit être de type booléen ou booléenne, sinon une erreur de compilation se produit.

5voto

romaintaz Points 32120
int count = isHere ? getHereCount(index) : getAwayCount(index);

signifie :

if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}

5voto

RichN Points 2615

Pas exactement correct, pour être précis :

  1. si isHere est vrai, le résultat de getHereCount() est a retourné
  2. otheriwse the résultat de getAwayCount() est a retourné

Le terme "retourné" est très important. Cela signifie que les méthodes debe retourner une valeur et cette valeur debe être affecté quelque part.

Aussi, c'est pas exactement syntaxiquement équivalent à la version if-else. Par exemple :

String str1,str2,str3,str4;
boolean check;
//...
return str1 + (check ? str2 : str3) + str4;

S'il est codé avec if-else, il produira toujours plus de bytecode.

0 votes

Je crois que javac a la liberté de générer le même bytecode. Bien que vous ayez raison de dire qu'il existe d'obscurs cas particuliers où ils ne sont pas équivalents.

0 votes

Oui, bien sûr. Pour moi, le véritable mérite de l'opérateur conditionnel est l'exemple que j'ai donné. L'alternative est soit : // gasp !! String temp = str1 ; if (check) temp += str2 ; else temp += str3 ; temp += str4 ; return temp ; ou bien coder manuellement l'opération d'append du StringBuilder. La première opération souffre d'un sérieux problème d'efficacité tandis que la seconde est trop verbeuse et représente un effort laborieux sans grand gain.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X