Sobes.tech
Middle

O que é um wildcard em Java?

sobes.tech IA

Resposta da IA

O curinga (?) em Java é usado em genéricos para representar um tipo desconhecido. Permite trabalhar com coleções que contêm elementos de tipos compatíveis diferentes, sem estar estritamente ligado a um tipo específico.

Os principais cenários de uso:

  1. ? (Curinga com limite superior): Indica qualquer tipo que seja um subtipo ou implemente a interface especificada. Usado para ler dados de uma coleção. Exemplo: List<? extends Number> pode conter List<Integer>, List<Double>, .getList<Long>.

    // Leitura de uma coleção com limite superior
    public void processNumbers(List<? extends Number> numbers) {
        for (Number n : numbers) {
            System.out.println(n);
        }
        // numbers.add(new Integer(10)); // Erro de compilação - não é possível adicionar elementos
    }
    
  2. ? super (Curinga com limite inferior): Indica qualquer tipo que seja um supertipo da classe/interface especificada ou essa própria classe/interface. Usado para escrever em uma coleção (princípio PECS: Produtor Extends, Consumidor Super). Exemplo: List<? super Integer> pode conter List<Integer>, List<Number>, List<Object>.

    // Escrita em uma coleção com limite inferior
    public void addIntegers(List<? super Integer> list) {
        list.add(1);
        list.add(new Integer(2));
        // Object o = list.get(0); // Retorna Object, pois o tipo exato é desconhecido
    }
    
  3. ? (Curinga sem limite): Indica qualquer tipo. Equivale a ? extends Object. Usado quando o tipo exato dos elementos da coleção não importa, por exemplo, para verificar o tamanho ou limpar.

    // Trabalhar com uma coleção de qualquer tipo
    public void printList(List<?> list) {
        for (Object obj : list) {
            System.out.println(obj);
        }
        // list.add("hello"); // Erro de compilação - não é possível adicionar elementos (exceto null)
    }
    

Os curings aumentam a flexibilidade do código, permitindo que métodos trabalhem com uma gama mais ampla de tipos de coleções, mantendo a segurança de tipos. Com eles, é possível evitar a duplicação de código para métodos que realizam operações semelhantes em coleções de tipos diferentes, mas compatíveis.