Como criar um array genérico em Java? Análise completa com exemplos

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

«Generic array creation» — erro que irrita todo desenvolvedor Java

\n\n

Você já escreveu algo como new T[10] e recebeu uma onda vermelha do compilador? Se sim, você não está sozinho. A pergunta «How can I create a generic array in Java?» no Stack Overflow acumulou centenas de milhares de visualizações. E não é por acaso: criar um array genérico em Java é um daqueles tópicos onde a teoria diverge da prática, e a IDE se recusa a entender o que você quer dela.

\n\n

Neste artigo, vamos analisar por que o Java proíbe arrays genéricos, como contornar a limitação sem perder a segurança de tipos e quando o array ainda é melhor que ArrayList. Vamos lá!

\n\n

Por que new T[10] não funciona? A raiz do mal — apagamento de tipos

\n\n

Para entender como criar um array genérico em Java, primeiro é preciso compreender por que o compilador reclama. A questão é o type erasure (apagamento de tipos). Os genéricos do Java existem apenas em tempo de compilação. Durante a execução, a informação do tipo T é apagada e substituída por Object (ou pelo limite, se definido).

\n\n

Já os arrays em Java são tipos reificáveis. Eles conhecem o tipo de seus componentes em tempo de execução. Portanto, a JVM pode verificar se você está colocando no array apenas elementos do tipo correto. Se você pudesse escrever new T[10], em tempo de execução o array seria Object[], e você poderia colocar String, Integer e Date simultaneamente — o que viola toda a ideia de segurança de tipos.

\n\n

É por isso que o compilador gera o erro:

\n
// ❌ Erro de compilação: generic array creation\npublic class Box<T> {\n    private T[] array = new T[10];  // Cannot create a generic array of T\n}
\n\n

Método 1: O mais simples — use ArrayList

\n\n

Na maioria das vezes, você nem precisa de um array. O ArrayList internamente trabalha com Object[], mas fornece uma interface segura quanto ao tipo. É a solução ideal se você não está obcecado com desempenho em nível de nanossegundos.

\n\n
import java.util.ArrayList;\nimport java.util.List;\n\npublic class GenericListExample<T> {\n    private List<T> list = new ArrayList<>();\n\n    public void add(T item) {\n        list.add(item);\n    }\n\n    public T get(int index) {\n        return list.get(index);\n    }\n\n    public int size() {\n        return list.size();\n    }\n}
\n\n

Vantagens: segurança total de tipos, sem avisos, suporte a expansão dinâmica.
\nDesvantagens: pequena sobrecarga de boxing/unboxing para primitivos (mas para 99% das aplicações isso é imperceptível).

\n\n

Método 2: O truque clássico com (T[]) new Object[size]

\n\n

Se você realmente precisa de um array (por exemplo, para desempenho ou compatibilidade com APIs legadas), pode usar um cast de tipos. Isso é seguro se você garantir que o array nunca saia dos limites da sua classe.

\n\n
public class Stack<T> {\n    private T[] elements;\n    private int size = 0;\n    private static final int DEFAULT_CAPACITY = 10;\n\n    @SuppressWarnings("unchecked")\n    public Stack() {\n        elements = (T[]) new Object[DEFAULT_CAPACITY];\n    }\n\n    public void push(T item) {\n        if (size == elements.length) {\n            resize();\n        }\n        elements[size++] = item;\n    }\n\n    public T pop() {\n        if (size == 0) {\n            throw new EmptyStackException();\n        }\n        T result = elements[--size];\n        elements[size] = null;  // Ajuda o GC\n        return result;\n    }\n\n    private void resize() {\n        elements = Arrays.copyOf(elements, elements.length * 2);\n    }\n}
\n\n

Importante: a anotação @SuppressWarnings("uncheck

Blogs

Book Recommendations