Java no permite matrices de clases internas para una clase genérica

Sé que no puede crear una matriz de un tipo genérico, sino que tiene que recurrir a un hack. (Dado que Java admite matrices genéricas, pero no su creación, no tengo claro por qué un hack es mejor que Java que admite la creación de matrices genéricas)

En lugar de escribir esto

Map.Entry[] entries = new Map.Entry[numEntries]; 

tienes que escribir esto

 @SuppressWarnings("unchecked") Map.Entry[] entries = (Map.Entry) new Map.Entry[numEntries]; 

Desafortunadamente, esto no funciona si tiene una matriz de tipo nested de un genérico

 public class Outer { final Inner[] inners = new Inner[16]; // Generic array creation class Inner { } } 

El mejor trabajo alrededor parece ser

 @SuppressWarnings("unchecked") final Inner[] inners = (Inner[]) Array.newInstance(Inner.class, 16); 

¿Es esta la solución más “elegante”?


Hago ver un error de comstackción de creación de matriz genérica de la clase interna, pero la solución aquí es peor, en mi humilde opinión.

Haz lo siguiente:

 @SuppressWarnings("unchecked") final Inner[] inners = (Inner[])new Outer.Inner[16]; 

El equivalente a su primer ejemplo hubiera sido el new Outer.Inner[16] pero esto aislará la new Outer.Inner[16] no seleccionada y evitará el tipo sin new Outer.Inner[16] .

Lo que debe tener en cuenta es que su situación es la misma que la primera situación que describió.

Inner es una clase interna no estática de Outer , una clase genérica. Eso significa que Inner está dentro del scope del parámetro type, y simplemente escribir Inner es la abreviatura de Outer.Inner . es decir, puede que no lo parezca, pero simplemente Inner es un tipo parametrizado, como Map.Entry , porque el parámetro de tipo E de la clase externa se convierte implícitamente en un parámetro de tipo de la clase interna. La solución a ambos problemas es la misma.

Su solución al primer problema fue crear una matriz del tipo en bruto, es decir, new Map.Entry[numEntries]; . ¿Cuál es el tipo crudo aquí? No Inner , como ya hemos comentado. En su lugar, debe calificar explícitamente el tipo externo para acceder al tipo sin new Outer.Inner[16]; : new Outer.Inner[16]; . Por supuesto, necesita una conversión para volver a convertirla en el tipo de matriz genérica deseada:

 (Inner[])new Outer.Inner[16] 

Hay otra forma de crear una matriz de un tipo genérico, sin usar un tipo sin procesar: usar un tipo de comodín, es decir, un new Map.Entry[numEntries]; . El equivalente para nuestro caso sería new Outer.Inner[16]; . Con el elenco:

 (Inner[])new Outer.Inner[16] 

¿Es una opción para ti hacer que la clase interna sea static ?

Si eso es posible, deberías poder crear una matriz de la clase interna usando la forma estándar:

 public class Outer { final Inner[] inners = new Inner[16]; // works static class Inner { } }