Sobes.tech
Middle

Quais são as possibilidades em Generics?

sobes.tech IA

Resposta da IA

Os genéricos permitem criar classes, interfaces e métodos parametrizados.

Principais funcionalidades:

  • Reutilização de código: Criação de estruturas de dados e algoritmos universais que funcionam com qualquer tipo.
  • Segurança de tipos em tempo de compilação: Os erros de tipo são detectados na fase de compilação, não em tempo de execução. Elimina a necessidade de fazer conversões de tipos manuais e erros potenciais relacionados ClassCastException.
  • Melhor legibilidade: O código torna-se mais compreensível, pois indica claramente com que tipos trabalha.

Exemplos:

  • A classe contêiner List<T> pode armazenar elementos de qualquer tipo T.
  • O método static <T> T getFirst(List<T> list) pode devolver o primeiro elemento de uma lista de qualquer tipo.

Restrições dos genéricos:

  • Não é possível criar instâncias de tipos genéricos: new T().
  • Não é possível usar tipos primitivos como parâmetros de tipo (por exemplo, List<int> - incorreto, deve usar List<Integer>).
  • Não é possível criar arrays de tipos genéricos diretamente (por exemplo, T[] array = new T[10] - incorreto, deve usar ArrayList ou fazer um casting).
  • Não é possível usar campos estáticos de tipos genéricos diretamente.
  • A informação de tipos é apagada em tempo de execução (Type Erasure), exceto pelos wildcards limitados.

Wildcards e parâmetros de tipo limitados:

  • <?> : Tipo desconhecido. Permite ler elementos, mas não escrever.
  • <? extends T> : Limite superior. Permite trabalhar com tipos que são subtipos de T. Pode ler elementos de tipo T ou seus supertipos, mas não escrever (exceto null).
  • <? super T> : Limite inferior. Permite trabalhar com tipos que são supertipos de T. Pode escrever elementos de tipo T ou seus subtipos, mas ao ler apenas se obtém Object.

Exemplo:

// Método que pode imprimir elementos de qualquer lista,
// que contém subtipos de Number
public static void printNumbers(List<? extends Number> list) {
    for (Number n : list) {
        System.out.println(n);
    }
    // list.add(new Integer(1)); // Erro de compilação
}

// Método que pode adicionar Integer a uma lista,
// que contém Integer ou seus supertipos
public static void addIntegers(List<? super Integer> list) {
    list.add(new Integer(10));
    // Integer val = list.get(0); // Erro de compilação, retorna Object
}