Operador Ternario en Java
Escribe expresiones condicionales concisas en Java con el operador ternario (condición ? a : b).
El operador ternario ?: es el único operador de Java que toma tres operandos. Es un if/else compacto para expresiones, no sentencias — es decir, evalúa a un valor que puedes asignar, retornar o pasar como argumento. Esta página cubre su sintaxis, dónde se lee bien, las reglas de tipos que gobiernan las dos ramas y cuándo usar if/else o switch en su lugar.
Sintaxis
condition ? valueIfTrue : valueIfFalseSi condition es true, toda la expresión evalúa a valueIfTrue. De lo contrario, evalúa a valueIfFalse. Java elige uno — y solo uno — de los dos valores para calcular.
int age = 20;
String status = (age >= 18) ? "adult" : "minor";
System.out.println(status); // adultLos paréntesis alrededor de la condición son opcionales; muchas guías de estilo los recomiendan por claridad.
Dónde brilla
El operador ternario está en su mejor momento para asignaciones únicas o como parte de una expresión más grande donde un if/else te obligaría a romper la línea:
int max = (a > b) ? a : b;
String label = items.isEmpty() ? "no items" : items.size() + " items";
System.out.println("Hello, " + (name != null ? name : "stranger") + "!");La última forma es especialmente útil: te permite elegir un valor en línea sin introducir una variable temporal.
Los tipos deben ser compatibles
Ambas ramas de un ternario deben producir tipos compatibles. El compilador elige el tipo común más general para toda la expresión:
int x = 5;
double d = (x > 0) ? x : 0.0; // result type is doubleRamas verdaderamente incompatibles — donde ningún valor puede convertirse al otro y el tipo destino no puede aceptar ambos — causan un error de compilación:
// won't compile: String cannot be converted to int
int n = condition ? 1 : "two";Dos tipos de referencia no relacionados, en cambio, están bien si el destino es suficientemente general para contener cualquier resultado. Aquí ambas ramas se amplían a su supertipo común, Object:
Object value = condition ? "yes" : 42; // 42 is autoboxed to Integer; type is ObjectSi necesitas específicamente un tipo particular, convierte una rama para que el tipo inferido coincida con lo que esperas.
No anides profundamente
Puedes anidar ternarios — pero más allá de un nivel, se vuelven difíciles de leer:
String grade = (score >= 90) ? "A"
: (score >= 80) ? "B"
: (score >= 70) ? "C"
: "F";Eso es límite; muchos equipos prohíben incluso esto. Para más de dos ramas, una cadena if/else if o un switch es casi siempre más claro. Usa el ternario cuando haya exactamente dos resultados posibles.
Ternario vs if/else
Ambos compilan esencialmente al mismo bytecode, así que no es una elección de rendimiento — es una de legibilidad. Las reglas generales:
- Usa un ternario cuando necesites un valor — asignar, retornar o interpolar.
- Usa
if/elsecuando necesites sentencias — efectos secundarios, múltiples líneas, registro.
// good ternary use:
return (errors == 0) ? "OK" : "FAIL";
// bad ternary use — side effects in branches:
boolean ok = (x > 0) ? logSuccess() : logFailure();El segundo ejemplo funciona, pero enterrar efectos secundarios dentro de una expresión condicional oculta el flujo de control. Exprésalo con if/else.
Valores predeterminados seguros con null
Un patrón común: recurrir a un valor predeterminado cuando algo es null:
String displayName = (user.name != null) ? user.name : "Anonymous";Si te encuentras escribiendo esto con frecuencia, el JDK tiene un método auxiliar — Objects.requireNonNullElse:
import java.util.Objects;
String displayName = Objects.requireNonNullElse(user.name, "Anonymous");Un ejemplo trabajado
Qué sigue
Para despachar sobre un único valor entre muchos casos, la sentencia switch es más legible que una larga cadena ternaria. Para ramificación de tipo sentencia con efectos secundarios, usa if/else, y consulta el conjunto completo de operadores de comparación y lógicos en operadores de Java.