1

Salut smile

Je n'ai pas eu le temps de chercher la réponse (tongue) mais juste en passant, si quelqu'un à une vague idée de la raison pour laquelle la première version ne compile pas... (la seconde ça passe, mais bon, je ne vois pas bien le problème de la première...)

ArrayList<String>[] als= new ArrayList<String>[] {} ; // compile pas : "Cannot create a generic array of Arraylist<String>"

@SuppressWarnings("unchecked")
ArrayList<String>[] als2= new ArrayList[] {} ; // compile



Faudrait que je relise le tuto des Generics, mais là je n'ai pas trop le temps (deadline, toussa...)

Merci d'avance !

2

PS : le problème n'a rien à voir avec arraylist, ça fait pareil dès qu'on utilise un type générique.

3

Je suppose que c'est un "feature" des generics Java. sick
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

4

En vrai c'est une feature qui vient d'un bug. Les tableaux n'ont pas été correctement typés en Java. Tu peux faire ca:
Object[] t = new String[1];
t[0] = new Integer(1);

ca compile, ca plante au runtime. Si tu utilises une ArrayList (qui avec les génériques est correctement typé) au lieu d'un tableau:
ArrayList<Object> t = new ArrayList<String>();
t.add(new Integer(1));

Et la ca compile pas. Normal. Ce qui aurait du être le cas pour les tableaux.

Après on peut se dire qu'on pourrait faire compiler ce code en utilisant le bug du typage des tableaux. t devient un tableau et pas seulement une variable:
ArrayList<Object>[] t = new ArrayList<String>[0];
t[0] = new ArrayList<Object>();
t[0].add(new Integer(1));

Et donc ca planterait à la derniere ligne.

Donc finalement, comme tu peux ne pas savoir ce qu'il y a dans un tableau, même si c'est typé, autant obliger à créer des raw types, comme ca tu peux être sûr que ca marche, pas de bug de runtime.

5

merci wink

6

s tableaux tu peux faire compiler du code qui met n'importe quoi dans un tableau de n'importe quoi, *mais* comme ce problème de typage est connu, le type est quand même vérifié au runtime au moment de l'affectation (comme pour un cast), et s'il n'est pas compatible avec le type du tableau ça lance une exception (ArrayAssignmentError ou un truc comme ça). En fait en théorie les génériques ne devraient rien changer à ça, et :Object[] t = new ArrayList<String>[0]; t[0] = new ArrayList<Object>(); t[0].add(new Integer(1));En fait c'est un peu plus subtil que ça. Le fait est qu'en raison du sous-typage inconsistant sur lelancerait cette exception à la deuxième ligne et non à la troisième (parce que ArrayList<Object> n'est pas un sous-type de ArrayList<String>, qui est le type requis pour les éléments du tableaux).

Mais le problème c'est qu'on ne peut pas faire un test au runtime sur le paramètre d'un générique, l'information disparaît à la compilation, au runtime tout ce qu'il sait c'est que c'est une ArrayList ; donc en fait il ne serait même pas possible de détecter l'erreur à ce moment-là et déclencher l'exception, et comme le dit hibou c'est seulement à la ligne suivante que ça serait détecté... c'est pour éviter ça que tu ne peux pas créer de tableau ayant un type paramétré.

Par contre tu n'es pas obligé d'utiliser un raw type, tu peux faire un new ArrayList<?>[], c'est mieux happy
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

7

effectivement j'avait oublié que la deuxème ligne passe pas. tongue

Par contre, pour le coup du "new ArrayList<?>[]", l'inconvenient est qu'il devient en lecture seule. Et la pour le coup la troisième ligne ne compile plus.
Et y'a un truc que je me suis toujours demandé : "T<?>" est le raccourcis de "T<? extends Object>" non ?

8

« If no bound is given for a type variable, Object is assumed. »
donc je dirais oui ^^. Enfin c'est sémantiquement équivalent quoi, mais par contre c'est possible qu'en l'occurrence il refuse qu'on mette un extends sans vérifier si c'est Object ou pas...

hum sinon tu dois pouvoir le caster sauvagement non ? (flemme de vérifier s'il l'accepte) bon du coup c'est largement aussi crade que d'utiliser un raw type, certes, mais bon cheeky (d'ailleurs ça doit revenir plus ou moins au même sémantiquement en fait ^^)

(je veux dire Machin<T>[] truc = (Machin<T>[]) new Machin<?>[])
avatar
« Le bonheur, c'est une carte de bibliothèque ! » — The gostak distims the doshes.
Membrane fondatrice de la confrérie des artistes flous.
L'univers est-il un dodécaèdre de Poincaré ?
(``·\ powaaaaaaaaa ! #love#

9

ok si tu fait un cast, mais pour le coup <?> ne sert plus à rien, et donc on revient à ce qu'a trouvé Pen^2 tongue

bref, les génériques, c'est pas automatique !

10

grin

(merci pour les réponses)