Operador Ternário Java
Escreva expressões condicionais concisas em Java com o operador ternário (condição ? a : b).
O operador ternário ?: é o único operador Java que recebe três operandos. É um if/else compacto para expressões, não instruções — o que significa que ele resulta em um valor que você pode atribuir, retornar ou passar como argumento. Esta página cobre sua sintaxe, onde ele é legível, as regras de tipo que regem os dois ramos e quando usar if/else ou switch em vez disso.
Sintaxe
condition ? valueIfTrue : valueIfFalseSe condition for true, toda a expressão avalia para valueIfTrue. Caso contrário, avalia para valueIfFalse. O Java escolhe um — e somente um — dos dois valores para calcular.
int age = 20;
String status = (age >= 18) ? "adult" : "minor";
System.out.println(status); // adultOs parênteses ao redor da condição são opcionais; muitos guias de estilo os recomendam para maior clareza.
Onde ele brilha
O operador ternário é melhor para atribuições únicas ou como parte de uma expressão maior onde um if/else forçaria você a quebrar a linha:
int max = (a > b) ? a : b;
String label = items.isEmpty() ? "no items" : items.size() + " items";
System.out.println("Hello, " + (name != null ? name : "stranger") + "!");A última forma é especialmente útil: permite escolher um valor inline sem introduzir uma variável temporária.
Os tipos devem ser compatíveis
Ambos os ramos de um operador ternário devem produzir tipos compatíveis. O compilador escolhe o tipo comum mais geral para toda a expressão:
int x = 5;
double d = (x > 0) ? x : 0.0; // result type is doubleRamos verdadeiramente incompatíveis — onde nenhum valor pode ser convertido para o outro e o tipo de destino não aceita ambos — causam um erro de compilação:
// won't compile: String cannot be converted to int
int n = condition ? 1 : "two";Dois tipos de referência não relacionados, ao contrário, são válidos se o destino for genérico o suficiente para conter qualquer resultado. Aqui, ambos os ramos são ampliados para seu supertipo comum, Object:
Object value = condition ? "yes" : 42; // 42 is autoboxed to Integer; type is ObjectSe você precisar especificamente de um tipo particular, faça cast em um dos ramos para que o tipo inferido corresponda ao esperado.
Não aninhe profundamente
Você pode aninhar operadores ternários — mas além de um nível, eles se tornam difíceis de ler:
String grade = (score >= 90) ? "A"
: (score >= 80) ? "B"
: (score >= 70) ? "C"
: "F";Isso é borderline; muitas equipes proíbem até isso. Para mais de dois ramos, uma cadeia if/else if ou um switch é quase sempre mais claro. Use o operador ternário quando houver exatamente dois resultados.
Ternário vs if/else
Ambos compilam essencialmente para o mesmo bytecode, portanto não é uma escolha de desempenho — é de legibilidade. As regras práticas:
- Use um ternário quando você precisa de um valor — atribuindo, retornando ou interpolando.
- Use
if/elsequando você precisa de instruções — efeitos colaterais, múltiplas linhas, logging.
// good ternary use:
return (errors == 0) ? "OK" : "FAIL";
// bad ternary use — side effects in branches:
boolean ok = (x > 0) ? logSuccess() : logFailure();O segundo exemplo funciona, mas enterrar efeitos colaterais dentro de uma expressão condicional oculta o fluxo de controle. Expresse-o com if/else.
Valores padrão null-safe
Um padrão comum: usar um valor padrão quando algo é null:
String displayName = (user.name != null) ? user.name : "Anonymous";Se você se pegar escrevendo isso com frequência, o JDK tem um utilitário — Objects.requireNonNullElse:
import java.util.Objects;
String displayName = Objects.requireNonNullElse(user.name, "Anonymous");Um exemplo prático
O que vem a seguir
Para despachar em um único valor entre muitos casos, o comando switch é mais legível do que uma longa cadeia ternária. Para ramificação no estilo de instruções com efeitos colaterais, use if/else, e veja o conjunto completo de operadores de comparação e lógicos em operadores Java.