Generics em Kotlin: para que servem e como usar para iniciantes

Treinador Online de Python para Iniciantes

Aprenda Python facilmente sem sobrecarga teórica. Resolva tarefas práticas com verificação automática e escreva código diretamente no navegador.

Start Course

Introdução aos Generics em Kotlin

\n\n

Ao desenvolver em Kotlin, mais cedo ou mais tarde você se deparará com uma situação em que o mesmo algoritmo ou estrutura de dados precisa funcionar com diferentes tipos de objetos. Imagine que você está escrevendo uma função para encontrar o elemento máximo em uma lista — ela deve lidar igualmente bem tanto com uma lista de números quanto com uma lista de strings. Sem ferramentas especiais, você teria que escrever implementações separadas para cada tipo. É aqui que os Generics (tipos genéricos ou generalizações) entram em ação.

\n\n

Generics em Kotlin é um mecanismo poderoso que permite criar classes, funções e interfaces que funcionam com diferentes tipos de dados, mantendo a tipagem estrita em tempo de compilação. Neste artigo, vamos entender para que servem os Generics e aprender a usá-los com exemplos práticos.

\n\n

O que são Generics e para que servem?

\n\n

Imagine uma caixa que pode guardar qualquer objeto: um livro, um telefone ou uma maçã. Na programação, essa "caixa" é uma classe ou função genérica. Sem Generics, você teria que usar o tipo Any (análogo ao Object em Java) e fazer conversões de tipo constantemente, o que é propenso a erros.

\n\n

O problema sem Generics

\n\n
fun <T> printList(list: List<T>) {\n    for (item in list) {\n        println(item)\n    }\n}\n\n// Sem Generics, teria que ser escrito assim:\nfun printListAny(list: List<Any>) {\n    for (item in list) {\n        // É necessário verificar o tipo e converter\n        if (item is String) {\n            println("String: $item")\n        } else if (item is Int) {\n            println("Número: $item")\n        }\n    }\n}
\n\n

Vantagens do uso de Generics

\n\n
    \n
  • Segurança de tipos — o compilador verifica a correta utilização dos tipos em tempo de compilação.
  • \n
  • Reutilização de código — uma função ou classe funciona com qualquer tipo.
  • \n
  • Eliminação de conversões explícitas — o código fica mais limpo e menos sujeito a erros.
  • \n
  • Desempenho — não há custos adicionais com verificação de tipos em tempo de execução.
  • \n
\n\n

Principais construções de Generics em Kotlin

\n\n

1. Funções Genéricas

\n\n

Uma função genérica é uma função que aceita um parâmetro de tipo. Ela é declarada usando colchetes angulares <T> antes do nome da função.

\n\n
fun <T> getFirstElement(list: List<T>): T? {\n    return list.firstOrNull()\n}\n\nfun main() {\n    val numbers = listOf(1, 2, 3, 4, 5)\n    val firstNumber = getFirstElement(numbers)\n    println("Primeiro número: $firstNumber") // 1\n\n    val words = listOf("Gato", "Cachorro", "Papagaio")\n    val firstWord = getFirstElement(words)\n    println("Primeira palavra: $firstWord") // Gato\n}
\n\n

Observe: o tipo T é inferido automaticamente pelo compilador. Você pode especificá-lo explicitamente, mas isso não é obrigatório:

\n\n
val firstNumber = getFirstElement<Int>(numbers)
\n\n

2. Classes Genéricas

\n\n

Uma classe genérica é uma classe que pode armazenar e manipular objetos de qualquer tipo. Um excelente exemplo é a classe padrão Box.

\n\n
class Box<T>(private val content: T) {\n    fun getContent(): T {\n        return content\n    }\n\n    fun isTypeOf(typeClass: Class<*>): Boolean {\n        return typeClass.isInstance(content)\n    }\n}\n\nfun main() {\n    val stringBox = Box("Olá, mundo!")\n    println(stringBox.getContent()) // Olá, mundo!\n\n    val intBox = Box(42)\n    println(intBox.getContent()) // 42\n\n    // Verificação de tipo\n    println(intBox.isTypeOf(Int::class.java)) // true\n}
\n\n

3. Interfaces Genéricas

\n\n

Interfaces também podem ser genéricas. Isso é especialmente útil ao criar coleções ou contratos para processamento de dados.

\n\n
interface Repository<T> {\n                

Blogs

Book Recommendations