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?

Jakob Weisblat
la source

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)

Daniel Gratzer
la source
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é").

DépriméDaniel
la source
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.

Code zéro
la source