Operatore Ternario Java
Scrivi espressioni condizionali concise in Java con l'operatore ternario (condizione ? a : b).
L'operatore ternario ?: è l'unico operatore Java che accetta tre operandi. È una forma compatta di if/else per le espressioni, non per le istruzioni — il che significa che restituisce un valore che puoi assegnare, restituire o passare come argomento. Questa pagina tratta la sintassi, i casi in cui risulta leggibile, le regole di tipo che governano i due rami e quando preferire if/else o switch.
Sintassi
condition ? valueIfTrue : valueIfFalseSe condition è true, l'intera espressione restituisce valueIfTrue. Altrimenti restituisce valueIfFalse. Java valuta uno — e uno solo — dei due valori.
int age = 20;
String status = (age >= 18) ? "adult" : "minor";
System.out.println(status); // adultLe parentesi attorno alla condizione sono facoltative; molti stili guida le consigliano per chiarezza.
Quando brilla
L'operatore ternario è al meglio per assegnazioni singole o come parte di un'espressione più ampia in cui un if/else costringerebbe a spezzare la riga:
int max = (a > b) ? a : b;
String label = items.isEmpty() ? "no items" : items.size() + " items";
System.out.println("Hello, " + (name != null ? name : "stranger") + "!");L'ultima forma è particolarmente comoda: permette di scegliere un valore inline senza introdurre una variabile temporanea.
I tipi devono essere compatibili
Entrambi i rami di un'espressione ternaria devono produrre tipi compatibili. Il compilatore sceglie il tipo comune più generale per l'intera espressione:
int x = 5;
double d = (x > 0) ? x : 0.0; // result type is doubleRami veramente incompatibili — in cui nessun valore può essere convertito nell'altro e il tipo di destinazione non può accettare entrambi — causano un errore di compilazione:
// won't compile: String cannot be converted to int
int n = condition ? 1 : "two";Due tipi riferimento non correlati, al contrario, vanno bene se il tipo di destinazione è abbastanza generale da contenere entrambi i risultati. Qui entrambi i rami vengono ampliati al loro supertipo comune, Object:
Object value = condition ? "yes" : 42; // 42 is autoboxed to Integer; type is ObjectSe hai bisogno di un tipo specifico, esegui il cast di un ramo in modo che il tipo inferito corrisponda a quello atteso.
Non annidare in profondità
Puoi annidare gli operatori ternari — ma oltre un livello diventano difficili da leggere:
String grade = (score >= 90) ? "A"
: (score >= 80) ? "B"
: (score >= 70) ? "C"
: "F";Questo è al limite; molti team vietano persino questo. Per più di due rami, una catena if/else if o uno switch è quasi sempre più chiara. Usa l'operatore ternario quando ci sono esattamente due esiti.
Ternario vs if/else
Entrambi compilano essenzialmente nello stesso bytecode, quindi non è una scelta di prestazioni — è una questione di leggibilità. Le regole pratiche:
- Usa l'operatore ternario quando hai bisogno di un valore — da assegnare, restituire o interpolare.
- Usa
if/elsequando hai bisogno di istruzioni — effetti collaterali, più righe, logging.
// good ternary use:
return (errors == 0) ? "OK" : "FAIL";
// bad ternary use — side effects in branches:
boolean ok = (x > 0) ? logSuccess() : logFailure();Il secondo esempio funziona, ma nascondere effetti collaterali all'interno di un'espressione condizionale offusca il flusso di controllo. Scrivilo per esteso con if/else.
Valori predefiniti null-safe
Un pattern comune: ricorrere a un valore predefinito quando qualcosa è null:
String displayName = (user.name != null) ? user.name : "Anonymous";Se ti trovi a scrivere questo spesso, il JDK offre un helper — Objects.requireNonNullElse:
import java.util.Objects;
String displayName = Objects.requireNonNullElse(user.name, "Anonymous");Esempio pratico
Cosa c'è dopo
Per selezionare tra molti casi su un singolo valore, l'istruzione switch è più leggibile di una lunga catena ternaria. Per la ramificazione con effetti collaterali, usa if/else, e consulta l'insieme completo di operatori di confronto e logici in operatori Java.