¿Por qué los genéricos Java no pueden estar en matrices?

Respuestas:

20

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 de Object[]y ParentOfFoo[]. Contrasta esto con List<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)

Daniel Gratzer
fuente
3

¿Hay alguna razón relacionada con la implementación de genéricos en Java, genéricos en cualquier idioma o algo arbitrario?

En realidad, es algo arbitrario.

El problema es que permite un agujero en el sistema de tipos, ya que ArrayList<T>[]puede fundirse Object[]y luego puede colocar un ArrayList<U>en la matriz, donde U != 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").

Daniel deprimido
fuente
Esta respuesta está subestimada. Muy simple y no usa jerga en términos vagos. Muchas gracias.
Tung Nguyen
Es posible que desee dar más detalles sobre por qué esto es diferente al caso en que se pone una Integeren una Object[]que en realidad es unString[]
Caleth
-3

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.

Código cero
fuente