Pourquoi les génériques Java ne peuvent-ils pas être dans les tableaux?


10

Pourquoi est-ce que lorsque j'essaye de faire un tableau de ArrayLists: ArrayList<Integer>[] arr=new ArrayList<Integer>[40];il y a une erreur et java ne le permet pas?

Y a-t-il une raison liée à l'implémentation par Java des génériques, des génériques dans n'importe quelle langue, ou quelque chose d'arbitraire?


Réponses:


20

C'est l'un des principaux trous dans les génériques Java, les tableaux sont covariants , ce qui signifie qu'un tableau de type Foo[]est une sous-classe de Object[]et ParentOfFoo[]. Comparez cela avec List<Foo>qui n'a pas ce comportement.

C'était important lorsque Java n'avait pas de génériques (jusqu'à Java 5) car sinon, quelque chose comme une fonction de tri générique était tout simplement impossible.

Cependant, il a ce problème délicat que les tableaux aiment savoir de quel type ils sont à l'exécution . Cependant, les génériques en Java sont basés sur l'effacement des types. Ces deux choses ne correspondent pas du tout bien et c'est là que nous obtenons notre problème.

Donc, en gros et en court, en Java 1, les tableaux covariants ont partiellement rempli le trou créé par le manque de génériques. Cependant, lorsqu'ils ont essayé de remplir correctement ce trou, la compatibilité descendante signifiait que les tableaux étaient assez impossibles à implémenter.

En fait, le gars qui a réellement créé le framework pour les génériques, Martin Odersky, en a parlé ici lors d'une interview sur les raisons pour lesquelles il a créé Scala. (Assez fascinant si vous êtes intéressé par l'histoire de Scala)


3

Y a-t-il une raison liée à l'implémentation par Java des génériques, des génériques dans n'importe quelle langue, ou quelque chose d'arbitraire?

En fait, c'est quelque peu arbitraire.

Le problème est qu'il permet un trou dans le système de type, car il ArrayList<T>[]peut être casté Object[]et vous pouvez ensuite placer un ArrayList<U>dans le tableau, où U != T.

Les concepteurs Java ont décidé de bloquer ce trou aussi ardemment que possible, en ne le permettant pas new ArrayList<T>[N]du tout.

Cependant, il aurait également pu être bloqué en ne permettant pas la conversion ascendante de tableaux de génériques (sans avertissement "non contrôlé").


Cette réponse est sous-estimée. Très simple et n'utilise pas de jargon en termes vagues. Merci beaucoup.
Tung Nguyen

Vous voudrez peut-être expliquer pourquoi cela est différent du cas où vous mettez un Integerdans un Object[]qui est en fait unString[]
Caleth

-3

car le tableau est covariant, chaque type étant une sous-classe de l'objet, ce qui donne une erreur d'exécution en raison d'une exception de transtypage. tandis que le générique est invariant, donc quand il s'appuie sur le type, assurez-vous que le type est sûr, donc si le type pas comme il crée le type, il donne une erreur de compilation.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.