W3docs

Opérateur ternaire en Java

Écrivez des expressions conditionnelles concises en Java avec l'opérateur ternaire (condition ? a : b).

L'opérateur ternaire ?: est le seul opérateur Java qui prend trois opérandes. C'est un if/else compact pour les expressions, et non les instructions — ce qui signifie qu'il s'évalue en une valeur que vous pouvez assigner, retourner ou passer en argument. Cette page couvre sa syntaxe, les cas où il est lisible, les règles de types qui régissent les deux branches, et quand préférer if/else ou switch à la place.

Syntaxe

condition ? valueIfTrue : valueIfFalse

Si condition est true, l'expression entière s'évalue en valueIfTrue. Sinon, elle s'évalue en valueIfFalse. Java choisit l'une — et une seule — des deux valeurs à calculer.

int age = 20;
String status = (age >= 18) ? "adult" : "minor";
System.out.println(status);   // adult

Les parenthèses autour de la condition sont facultatives ; de nombreux guides de style les recommandent pour la clarté.

Quand il brille

L'opérateur ternaire est à son meilleur pour les affectations uniques ou dans le cadre d'une expression plus large où un if/else vous forcerait à couper la ligne :

int max = (a > b) ? a : b;
String label = items.isEmpty() ? "no items" : items.size() + " items";
System.out.println("Hello, " + (name != null ? name : "stranger") + "!");

La dernière forme est particulièrement pratique : elle vous permet de choisir une valeur en ligne sans introduire de variable temporaire.

Les types doivent être compatibles

Les deux branches d'un opérateur ternaire doivent produire des types compatibles. Le compilateur choisit le type commun le plus général pour l'expression entière :

int x = 5;
double d = (x > 0) ? x : 0.0;   // result type is double

Des branches vraiment incompatibles — où aucune valeur ne peut être convertie en l'autre et le type cible ne peut pas accepter les deux — provoquent une erreur de compilation :

// won't compile: String cannot be converted to int
int n = condition ? 1 : "two";

Deux types de référence sans rapport, en revanche, sont acceptables si la cible est suffisamment générale pour contenir l'un ou l'autre résultat. Ici, les deux branches sont élargies à leur supertype commun, Object :

Object value = condition ? "yes" : 42;   // 42 is autoboxed to Integer; type is Object

Si vous avez besoin d'un type particulier, castez une branche afin que le type inféré corresponde à ce que vous attendez.

Évitez l'imbrication profonde

Vous pouvez imbriquer des opérateurs ternaires — mais au-delà d'un niveau, ils deviennent difficiles à lire :

String grade = (score >= 90) ? "A"
             : (score >= 80) ? "B"
             : (score >= 70) ? "C"
             : "F";

C'est limite ; de nombreuses équipes l'interdisent même ainsi. Pour plus de deux branches, une chaîne if/else if ou un switch est presque toujours plus clair. Utilisez l'opérateur ternaire quand il y a exactement deux résultats possibles.

Ternaire vs if/else

Les deux compilent vers essentiellement le même bytecode, donc ce n'est pas un choix de performance — c'est un choix de lisibilité. Les règles empiriques :

  • Utilisez un ternaire quand vous avez besoin d'une valeur — pour assigner, retourner ou interpoler.
  • Utilisez if/else quand vous avez besoin d'instructions — effets de bord, plusieurs lignes, journalisation.
// good ternary use:
return (errors == 0) ? "OK" : "FAIL";

// bad ternary use — side effects in branches:
boolean ok = (x > 0) ? logSuccess() : logFailure();

Le deuxième exemple fonctionne, mais enfouir des effets de bord dans une expression conditionnelle masque le flux de contrôle. Exprimez-le clairement avec if/else.

Valeurs par défaut null-safe

Un motif courant : revenir à une valeur par défaut quand quelque chose est null :

String displayName = (user.name != null) ? user.name : "Anonymous";

Si vous vous retrouvez à écrire cela souvent, le JDK dispose d'un utilitaire — Objects.requireNonNullElse :

import java.util.Objects;

String displayName = Objects.requireNonNullElse(user.name, "Anonymous");

Un exemple concret

java— editable, runs on the server

Et ensuite

Pour dispatcher sur une seule valeur parmi de nombreux cas, l'instruction switch est plus lisible qu'une longue chaîne ternaire. Pour les branchements de style instruction avec effets de bord, utilisez if/else, et consultez l'ensemble complet des opérateurs de comparaison et logiques dans les opérateurs Java.

Pratique

Pratique
Quelle valeur produit cette expression quand x vaut 0 ? x > 0 ? 'positive' : x < 0 ? 'negative' : 'zero'
Quelle valeur produit cette expression quand x vaut 0 ? x > 0 ? 'positive' : x < 0 ? 'negative' : 'zero'
Was this page helpful?