Como funciona a tipagem genérica (Generics) em Java?

A tipagem genérica (Generics) em Java permite criar classes, interfaces e métodos que podem operar sobre diferentes tipos, garantindo segurança e flexibilidade no código.

Como funciona a tipagem genérica (Generics) em Java?

A tipagem genérica ou Generics em Java permite criar classes, interfaces e métodos que podem operar sobre diferentes tipos sem perder segurança em tempo de compilação. Isso evita erros de conversão de tipo e elimina a necessidade de casting manual.

1. Benefícios do Uso de Generics

  • Reutilização de código: Um único código pode trabalhar com vários tipos de dados.
  • Segurança em tempo de compilação: Reduz erros ao garantir que os tipos corretos são utilizados.
  • Eliminação de casts desnecessários: Evita conversões explícitas de tipos, tornando o código mais limpo.

2. Criando uma Classe Genérica

Para criar uma classe genérica, usamos <T> como um parâmetro de tipo.

class Caixa<T> {
    private T conteudo;

    public void guardar(T item) {
        this.conteudo = item;
    }

    public T retirar() {
        return conteudo;
    }
}

Uso da classe genérica:

public class TesteGenerics {
    public static void main(String[] args) {
        Caixa<String> caixaDeTexto = new Caixa<>();
        caixaDeTexto.guardar("Olá, Generics!");
        System.out.println(caixaDeTexto.retirar()); // Olá, Generics!

        Caixa<Integer> caixaDeNumeros = new Caixa<>();
        caixaDeNumeros.guardar(42);
        System.out.println(caixaDeNumeros.retirar()); // 42
    }
}

Aqui, Caixa<T> funciona para qualquer tipo de dado, garantindo flexibilidade e segurança.

3. Generics com Múltiplos Tipos

Podemos definir classes genéricas com múltiplos parâmetros de tipo:

class Par<K, V> {
    private K chave;
    private V valor;

    public Par(K chave, V valor) {
        this.chave = chave;
        this.valor = valor;
    }

    public K getChave() {
        return chave;
    }

    public V getValor() {
        return valor;
    }
}

Uso:

Par<String, Integer> par = new Par<>("Idade", 30);
System.out.println(par.getChave() + ": " + par.getValor()); // Idade: 30

4. Restrições de Tipo com extends

Podemos restringir um tipo genérico para aceitar apenas subclasses de uma determinada classe ou interface:

class Calculadora<T extends Number> {
    private T numero;

    public Calculadora(T numero) {
        this.numero = numero;
    }

    public double aoQuadrado() {
        return numero.doubleValue() * numero.doubleValue();
    }
}

Isso impede que a classe seja usada com tipos não numéricos:

Calculadora<Integer> calc = new Calculadora<>(5);
System.out.println(calc.aoQuadrado()); // 25.0

5. Generics em Métodos

Podemos aplicar Generics diretamente a métodos, sem precisar criar uma classe genérica:

class Util {
    public static <T> void imprimir(T valor) {
        System.out.println(valor);
    }
}

Uso:

Util.imprimir("Texto Genérico");
Util.imprimir(123);

6. Uso de Generics com List e Map

Generics são amplamente usados em coleções Java:

List<String> lista = new ArrayList<>();
lista.add("Item 1");
lista.add("Item 2");

Map<Integer, String> mapa = new HashMap<>();
mapa.put(1, "Primeiro");
mapa.put(2, "Segundo");

Sem Generics, precisaríamos converter os valores manualmente, aumentando o risco de erros.

Conclusão

A tipagem genérica torna o código mais reutilizável, seguro e organizado. Utilizar Generics corretamente permite evitar conversões manuais, reduzir erros de tempo de execução e melhorar a legibilidade do código.

Generics são fundamentais para a robustez e flexibilidade da linguagem Java. Desde a introdução no Java 5, esse recurso tem sido amplamente utilizado em bibliotecas padrão como Collections, permitindo que classes como ArrayList<T> e HashMap<K, V> sejam genéricas e seguras. Além disso, frameworks modernos como Spring e Hibernate fazem uso intensivo de Generics para fornecer APIs mais poderosas e reutilizáveis. A compreensão desse conceito é essencial para qualquer desenvolvedor Java que deseja escrever código modular e escalável.

Algumas aplicações:

  • Criação de classes e métodos reutilizáveis
  • Uso eficiente de coleções como List e Map
  • Redução de erros de tipo em tempo de compilação
  • Facilidade na manipulação de dados em frameworks como Spring

Dicas para quem está começando

  • Use para criar classes e métodos genéricos
  • Prefira extends para restringir os tipos aceitos
  • Evite misturar tipos incompatíveis ao usar Generics
  • Pratique com List e Map para entender melhor
  • Explore como frameworks Java utilizam Generics para escrever código mais flexível

Contribuições de Rodrigo Farias

Compartilhe este tutorial: Como funciona a tipagem genérica Generics em Java

Compartilhe este tutorial

Continue aprendendo:

Como criar métodos genéricos em Java

Métodos genéricos em Java permitem criar funções que podem operar em diferentes tipos de dados, tornando o código mais reutilizável e flexível.

Tutorial anterior

Como utilizar toString hashCode e equals corretamente

Os métodos toString(), hashCode() e equals() são fundamentais em Java para representação, comparação e uso eficiente de objetos em coleções.

Próximo tutorial