Elvis Operator é um operador binário que retorna o operando esquerdo se não for null, e o direito caso contrário. É escrito como ?: em Kotlin, Groovy e algumas outras linguagens. De acordo com a Documentação da Linguagem Kotlin, 2024, o operador faz parte do sistema de segurança contra null da linguagem e permite encurtar construções condicionais para uma única linha sem perder legibilidade. Ao contrário de uma expressão if-else completa, o Elvis Operator avalia o lado direito apenas quando o lado esquerdo é null, proporcionando uma vantagem de desempenho ao usar expressões padrão caras.
Pontos-Chave
Elvis Operator é um operador binário nomeado em homenagem ao penteado de Elvis Presley. O símbolo ?: lembra visualmente o rosto do cantor de perfil: o ponto de interrogação é o olho e a costeleta, os dois pontos são a boca. O operador recebe dois operandos: se o primeiro não for null — ele é retornado, caso contrário o segundo é retornado. Isso permite substituir uma construção if-else completa por uma única expressão curta.
O nome “Elvis Operator” se consolidou nas comunidades de Kotlin e Groovy, e depois se espalhou para Xtend e outras linguagens JVM. Em Swift e Dart, a construção análoga é chamada de nil-coalescing operator, mas é funcionalmente idêntica. A associação visual com Elvis Presley ajudou o operador a se tornar um dos símbolos mais reconhecíveis na sintaxe das linguagens de programação modernas.
O Elvis Operator faz parte do sistema de null safety que previne NullPointerException (NPE). De acordo com um estudo da JetBrains de 2023, NPE representa 28% de todas as exceções em código JVM em produção. O uso do Elvis Operator elimina completamente NPE no ponto de atribuição, garantindo um valor padrão. Em combinação com o operador de chamada segura ?., uma cadeia confiável é criada sem um único bloco if.
Em Kotlin, o Elvis Operator é escrito como ?: entre duas expressões. Se a expressão esquerda não for null — o resultado é igual à expressão esquerda, caso contrário a direita é avaliada. A expressão direita é avaliada de forma preguiçosa — apenas quando o operando esquerdo é null, o que é importante para o desempenho ao usar cálculos caros ou chamadas de API.
val name: String? = getUserName()
val displayName = name ?: "Guest"
fun getLength(str: String?): Int {
return str?.length ?: 0
}
val config: Config? = loadConfig()
val timeout = config?.timeout ?: 30
println("Timeout: $timeout")
// Elvis com throw para parâmetros obrigatórios
val requiredId = nullableId ?: throw IllegalArgumentException("ID is required")
// Elvis com return para saída antecipada
fun process(data: String?): Result {
val safe = data ?: return Result.failure("No data")
return processInternal(safe)
}
Combinação com let é um padrão comum em Kotlin, onde o Elvis Operator fornece um valor padrão, e let executa uma ação no resultado não nulo. Essa abordagem substitui blocos if-else inteiros por uma única cadeia de chamadas sem perder legibilidade. O Elvis Operator também pode ser usado com throw para abortar forçosamente quando um parâmetro obrigatório está ausente — esta é uma forma idiomática de validar dados de entrada.
Um padrão comum em Kotlin é Elvis + return. Se o valor for null, a função retorna imediatamente um resultado ou lança uma exceção. O idioma Elvis com return é frequentemente usado em funções de transformação de dados: val processed = rawData ?: return defaultValue. Isso é mais compacto que guard let do Swift e não aumenta o aninhamento do código.
Elvis Operator é mais curto que if-else e não requer repetir a variável. Compare: val x = a ?: b versus val x = if (a != null) a else b. Com expressões complexas, a redução de código chega a 60%, enquanto a semântica é completamente idêntica — o compilador pode gerar o mesmo bytecode para ambas as variantes.
| Critério | Elvis Operator | if-else |
|---|---|---|
| Comprimento | 1 linha, 5–10 caracteres | 3 linhas, 15–30 caracteres |
| Repetição de expressão | Não | Sim (a != null) ? a : b |
| Lado direito preguiçoso | Sim | Sim (elvis é mais curto) |
| Efeitos colaterais | Apenas no lado direito | Em ambos os ramos |
| Legibilidade | Alta para casos simples | Melhor para lógica complexa |
O Elvis Operator é ideal para atribuir valores padrão, encadear chamadas de funções com acesso seguro e registrar valores ausentes. Padrões idiomáticos de Kotlin o recomendam como substituto de if-else para verificações simples de null em expressões. Combinado com ?., produz cadeias compactas sem variáveis temporárias.
if-else continua preferível para múltiplas condições, quando efeitos colaterais precisam ser executados, ou quando ambos os operandos são blocos de código complexos com várias operações. O Elvis Operator não suporta blocos aninhados — apenas expressões únicas para cada operando. Se o lado direito chama uma função com efeitos colaterais, a legibilidade de if-else é maior.
Groovy usa exatamente a mesma sintaxe ?: que Kotlin, já que ambas as linguagens rodam na JVM e compartilham a filosofia de null-safety. O operador apareceu antes em Groovy — está na linguagem desde a versão 1.8, lançada em 2011. Groovy também suporta atribuição Elvis: x ?= value (atribuir apenas se x for null).
def name = getUserName()
def display = name ?: "Guest"
def map = ["key": "value"]
def result = map?.get("missing") ?: "default"
println(result)
// Atribuição Elvis em Groovy
def config = null
config ?= "defaultConfig"
assert config == "defaultConfig"
Em Swift, o equivalente é chamado de nil-coalescing operator e é escrito como ??. Em Dart, a mesma sintaxe ?? é usada. A diferença é que Swift e Dart exigem correspondência de tipos dos operandos, enquanto Kotlin permite tipos diferentes com conversão automática para um supertipo comum. Em TypeScript, o operador ?? (nullish coalescing) apareceu na versão 3.7 e funciona apenas com null e undefined, ao contrário de || que filtra todos os valores falsy. Em PHP, o operador ?? apareceu na versão 7.0, em C# — ?? desde a versão 6.0.
O erro mais frequente é confundir o Elvis Operator ?: com o operador de chamada segura ?. Em Kotlin, ?. chama um método ou propriedade apenas se o objeto não for null, enquanto ?: retorna um valor padrão quando é null. Eles são combinados sequencialmente, mas cada um cumpre sua própria função. A confusão surge entre iniciantes que tentam usar ?: sem ?. antes.
O lado direito do Elvis é avaliado de forma preguiçosa, mas se contiver uma chamada de função com efeitos colaterais, pode levar a um comportamento inesperado. Os desenvolvedores às vezes colocam cálculos caros ou registro de eventos no lado direito, que não é executado quando o valor não é nulo. É importante lembrar que o lado direito é uma expressão que só é avaliada quando necessário.
Vários Elvis seguidos podem dificultar a leitura do código. Por exemplo, a ?: b ?: c ?: d é avaliado da esquerda para a direita, retornando o primeiro não nulo. O agrupamento com parênteses ou a extração da lógica em uma função separada melhora a legibilidade e facilita a depuração. Se a cadeia tiver mais de 3 elementos, deve-se usar uma expressão when ou uma função auxiliar.
Desenvolvedores iniciantes às vezes tentam usar o Elvis Operator para verificar valores booleanos: val x = flag ?: false. Isso só funciona se flag puder ser null. Para condições booleanas sem null, é necessário um if-else normal ou operador ternário — Kotlin não tem operador ternário, mas é substituído pela expressão if-else: val x = if (flag) a else b.
Perguntas Frequentes
Elvis Operator verifica apenas null, enquanto o operador ternário aceita qualquer condição booleana. Kotlin não tem operador ternário — ele é substituído pela expressão if-else. Elvis resolve uma tarefa específica: um valor padrão quando há null, enquanto o operador ternário cobre todas as expressões condicionais.
Sim, o lado direito pode ser uma chamada de função: val x = a ?: calculateDefault(). A função é avaliada apenas quando a é null graças à avaliação preguiçosa. Isso permite usar cálculos caros, chamadas de API ou consultas a banco de dados sem perda de desempenho quando um valor está presente.
Java não tem um Elvis Operator direto. A partir do Java 8, pode-se usar Optional.ofNullable(value).orElse(default). Java 14+ introduziu expressões switch, mas um ?: completo está ausente. Kotlin e Groovy o fornecem como uma construção sintática incorporada da linguagem.
O padrão típico é uma chamada segura ?. seguida de Elvis. Exemplo: user?.address?.city ?: “Unknown”. Se qualquer elemento da cadeia for null — o valor padrão é retornado. É uma substituição compacta para verificações if aninhadas, reduzindo o código em 3–5 vezes em comparação com a abordagem tradicional.
Elvis Operator é uma construção sintática a nível de linguagem, enquanto orElse é um método de Optional em Java. Elvis é preguiçoso (o lado direito só é avaliado quando null), enquanto orElse sempre avalia seu argumento. Para uma variante preguiçosa em Java, existe orElseGet, que aceita um Supplier. Elvis é mais curto e não requer a criação de um Optional.
Resumo
Vamos desenvolver um aplicativo móvel chave na mão
A IT Sectr cria aplicativos para iOS e Android para startups e empresas desde 2017. Nós vamos aconselhá-lo e propor a melhor solução.
Leia também