¿Por qué es eso cuando trato de hacer una matriz de ArrayLists: ArrayList<Integer>[] arr=new ArrayList<Integer>[40];
hay un error y Java no lo permite?
¿Hay alguna razón relacionada con la implementación de genéricos en Java, genéricos en cualquier idioma o algo arbitrario?
java
language-design
generics
Jakob Weisblat
fuente
fuente
Respuestas:
Este es uno de los principales agujeros en los genéricos de Java, las matrices son covariantes , lo que significa que una matriz de tipo
Foo[]
es una subclase deObject[]
yParentOfFoo[]
. Contrasta esto conList<Foo>
lo que no tiene este comportamiento.Esto era importante cuando Java no tenía genéricos (hasta Java 5) porque de lo contrario, algo así como una función de clasificación genérica era simplemente imposible.
Sin embargo, tiene este problema complicado que a las matrices les gusta saber de qué tipo son en tiempo de ejecución . Sin embargo, los genéricos en Java se basan en el borrado de tipo. Estas dos cosas no encajan bien y ahí es donde obtenemos nuestro problema.
Entonces, en resumen, en Java 1, las matrices covariantes llenaron parcialmente el vacío que creó la falta de genéricos. Sin embargo, cuando intentaron llenar adecuadamente este agujero, la compatibilidad con versiones anteriores significaba que las matrices eran bastante imposibles de implementar.
De hecho, el tipo que realmente creó el marco para los genéricos, Martin Odersky, habló sobre esto aquí durante una entrevista sobre por qué hizo Scala. (Bastante fascinante si te interesa la historia de Scala)
fuente
En realidad, es algo arbitrario.
El problema es que permite un agujero en el sistema de tipos, ya que
ArrayList<T>[]
puede fundirseObject[]
y luego puede colocar unArrayList<U>
en la matriz, dondeU != T
.Los diseñadores de Java decidieron bloquear este agujero lo más ansiosamente posible, al no permitirlo
new ArrayList<T>[N]
.Sin embargo, también podría haberse tapado al no permitir la transmisión de conjuntos de genéricos (sin una advertencia "no marcada").
fuente
Integer
en unaObject[]
que en realidad es unString[]
debido a que la matriz es covariante, cada tipo es una subclase del objeto, por lo que esto genera un error en el tiempo de ejecución debido a una excepción de conversión. mientras que el genérico es invariante, por lo tanto, cuando se basa en el tipo garantizar o seguro de tipo, por lo que si el tipo no es así, crea un error de compilador.
fuente