«instanceof» em Kotlin: por que não é Java, e como isso torna o código mais limpo
\n\nSe você veio para Kotlin do mundo Java, provavelmente está acostumado com a palavra-chave instanceof. Ela ajuda a saber se um objeto é uma instância de uma determinada classe. Mas em Kotlin esse operador não existe. E isso não é um bug, é uma funcionalidade.
Kotlin oferece uma maneira muito mais elegante, segura e concisa de verificar o tipo de um objeto — o operador is. Ele não apenas responde à pergunta "quem é você?", mas também converte automaticamente o objeto para o tipo necessário. Isso é chamado de smart cast (conversão inteligente), e é um dos recursos que tornam o código em Kotlin tão agradável.
Neste guia, abordaremos:
\n- \n
- Como usar o operador
isem vez deinstanceof; \n - O que é smart cast e como funciona; \n
- Como lidar elegantemente com vários tipos usando
when; \n - Qual a diferença entre a conversão segura
as?e a conversão comumas; \n - E, claro, exemplos reais de código. \n
Vamos lá!
\n\n1. Operador is — o análogo direto do instanceof
\n\nEm Java, você escreveria:
\nif (obj instanceof String) {\n String str = (String) obj;\n System.out.println(str.length());\n}\n\nEm Kotlin, a mesma coisa fica assim:
\nif (obj is String) {\n println(obj.length) // Smart cast! obj já é String\n}\n\nObserve: após a verificação obj is String, você não precisa converter explicitamente obj para o tipo String. O compilador Kotlin sabe que, dentro do bloco if, a variável obj é garantidamente uma string. Isso é o smart cast (conversão inteligente).
Como funciona internamente?
\nO compilador analisa o fluxo de execução. Se ele vê uma verificação is e não encontra a possibilidade de o tipo da variável mudar entre a verificação e o uso (por exemplo, em código multithread ou ao alterar var), ele converte o tipo automaticamente. Para val, isso funciona sempre; para var, funciona apenas se a variável não puder ser alterada entre a verificação e o uso.
2. Negação: !is
\n\nQuer verificar se o objeto não é de um tipo? Use !is:
if (obj !is String) {\n println("Isso não é uma string")\n} else {\n // Aqui obj automaticamente se torna String\n println("Tamanho da string: ${obj.length}")\n}\n\nConveniente e legível, não é?
\n\n3. Múltiplas verificações com when
\n\nAgora imagine que você tem um objeto que pode ser um de vários tipos. Em Java, você escreveria uma cadeia de if-else if com instanceof. Em Kotlin, existe uma ferramenta mais elegante — a construção when.
fun describe(obj: Any): String {\n return when (obj) {\n is String -> "String de tamanho ${obj.length}"\n is Int -> "Número inteiro: $obj"\n is List<*> -> "Lista com ${obj.size} elementos"\n is Map<*, *> -> "Mapa com ${obj.size} entradas"\n else -> "Tipo desconhecido"\n }\n}\n\nfun main() {\n println(describe("Olá")) // String de tamanho 4\n println(describe(42)) // Número inteiro: 42\n println(describe(listOf(1,2)))// Lista com 2 elementos\n}\n\nObserve: dentro de cada ramo do when, o smart cast também funciona! No ramo is String, a variável obj já é considerada uma string, e você pode chamar obj.length sem conversão adicional.
Isso é muito mais compacto e seguro do que o clássico switch ou uma cadeia de if.
4. Conversão segura: as?
\n\nÀs vezes, você não precisa apenas verificar o tipo, mas obter imediatamente o valor de um tipo específico. Em Java, você faria (String) obj