Por que quando tento criar uma matriz de ArrayLists: ArrayList<Integer>[] arr=new ArrayList<Integer>[40];
há um erro e o java não permite isso?
Existe um motivo relacionado à implementação de genéricos em java, genéricos em qualquer idioma ou algo arbitrário?
java
language-design
generics
Jakob Weisblat
fonte
fonte
Respostas:
Este é um dos principais buracos nos genéricos de Java, matrizes são covariantes , o que significa que uma matriz de tipo
Foo[]
é uma subclasse deObject[]
eParentOfFoo[]
. Compare isso com oList<Foo>
que não tem esse comportamento.Isso era importante quando o Java não possuía genéricos (até o Java 5) porque, caso contrário, algo como uma função de classificação genérica era simplesmente impossível.
No entanto, há um problema complicado que as matrizes gostam de saber que tipo são no tempo de execução . No entanto, os genéricos em Java são baseados no apagamento de tipo. Essas duas coisas não combinam bem e é aí que temos o nosso problema.
Portanto, em Java 1, as matrizes covariantes preencheram parcialmente o buraco que a falta de genéricos criou. No entanto, quando eles tentaram preencher adequadamente esse buraco, a compatibilidade com versões anteriores significou que as matrizes eram praticamente impossíveis de implementar.
De fato, o cara que realmente criou a estrutura para genéricos, Martin Odersky, falou sobre isso aqui durante uma entrevista sobre por que ele criou o Scala. (Muito fascinante se você estiver interessado na história de Scala)
fonte
Na verdade, é um tanto arbitrário.
O problema é que ele permite um furo no sistema de tipos, pois
ArrayList<T>[]
pode ser fundidoObject[]
e, em seguida, você pode colocar umArrayList<U>
na matriz, ondeU != T
.Os designers de Java decidiram bloquear esse buraco o mais ansiosamente possível, não permitindo
new ArrayList<T>[N]
.No entanto, ele também pode ter sido conectado ao não permitir upcasting de matrizes de genéricos (sem um aviso "não verificado").
fonte
Integer
umObject[]
que é realmente umString[]
porque a matriz é covariante, e todo tipo é uma subclasse do objeto, portanto, isso gera um erro no tempo de execução devido à exceção de conversão. enquanto o genérico é invariável, portanto, quando se baseia no tipo garanta ou seja seguro, para que, se o tipo não gostar dele, crie um erro, o erro seja compilado.
fonte