Cómo crear un array genérico en Java? Análisis completo con ejemplos

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

«Generic array creation» — el error que enfurece a todo desarrollador Java

\n\n

¿Alguna vez ha escrito algo como new T[10] y ha recibido una onda roja del compilador? Si es así, no está solo. La pregunta «How can I create a generic array in Java?» en Stack Overflow ha acumulado cientos de miles de visitas. Y no es casualidad: crear un array genérico en Java es uno de esos temas donde la teoría diverge de la práctica, y el IDE se niega a entender lo que usted quiere.

\n\n

En este artículo, analizaremos por qué Java prohíbe los arrays genéricos, cómo sortear la limitación sin perder seguridad de tipos, y cuándo un array sigue siendo mejor que un ArrayList. ¡Allá vamos!

\n\n

¿Por qué new T[10] no funciona? La raíz del mal: el borrado de tipos

\n\n

Para entender cómo crear un array genérico en Java, primero hay que comprender por qué el compilador se queja. Se trata del type erasure (borrado de tipos). Los genéricos de Java solo existen en tiempo de compilación. Durante la ejecución, la información del tipo T se borra y se sustituye por Object (o el límite, si se ha definido).

\n\n

Los arrays en Java, en cambio, son tipos reificables. Conocen el tipo de sus componentes en tiempo de ejecución. Por lo tanto, la JVM puede verificar que solo se introduzcan elementos del tipo correcto en el array. Si pudiera escribir new T[10], en tiempo de ejecución el array sería Object[], y podría poner String, Integer y Date al mismo tiempo, lo que viola toda la idea de seguridad de tipos.

\n\n

Por eso el compilador muestra el error:

\n
// ❌ Error de compilación: 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: El más simple — use ArrayList

\n\n

La mayoría de las veces ni siquiera necesita un array. ArrayList internamente trabaja con Object[], pero proporciona una interfaz con seguridad de tipos. Es la solución ideal si no está obsesionado con el rendimiento a nivel de nanosegundos.

\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

Ventajas: seguridad de tipos completa, sin advertencias, soporte para expansión dinámica.
\nDesventajas: una pequeña sobrecarga en el empaquetado/desempaquetado de primitivos (pero para el 99% de las aplicaciones es imperceptible).

\n\n

Método 2: El truco clásico con (T[]) new Object[size]

\n\n

Si realmente necesita un array (por ejemplo, por rendimiento o compatibilidad con una API heredada), puede usar un casting de tipos. Esto es seguro si garantiza que el array nunca saldrá de los límites de su clase.

\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;  // Ayudamos al GC\n        return result;\n    }\n\n    private void resize() {\n        elements = Arrays.copyOf(elements, elements.length * 2);\n    }\n}
\n\n

Importante: la anotación @SuppressWarnings("uncheck

Blogs

Book Recommendations