Lorsque vous ne faites pas vraiment des choses fantaisistes avec Java, je suis venu une erreur avec des génériques que je n'ai pas pu comprendre pourquoi cela ne fonctionne pas. Le code est: L'erreur que je reçois lors de la compilation est la suivante: p>
test/TestClass.java:11: incompatible types
found : test.TestClass.E<test.TestClass.D<test.TestClass.A>>
required: test.TestClass.E<test.TestClass.D<? extends test.TestClass.C>>
E<D<? extends C>> a = new E<D<A>>();
^
test/TestClass.java:12: incompatible types
found : test.TestClass.E<test.TestClass.D<? extends test.TestClass.C>>
required: test.TestClass.E<test.TestClass.D<? extends java.lang.Object>>
E<D<? extends Object>> b = new E<D<? extends C>>();
^
test/TestClass.java:13: incompatible types
found : test.TestClass.E<test.TestClass.D<test.TestClass.A>>
required: test.TestClass.E<test.TestClass.D<? extends test.TestClass.A>>
E<D<? extends A>> c = new E<D<A>>();
^
test/TestClass.java:14: incompatible types
found : test.TestClass.E<test.TestClass.D<test.TestClass.A>>
required: test.TestClass.E<test.TestClass.D<? super test.TestClass.A>>
E<D<? super A>> d = new E<D<A>>();
^
4 errors
10 Réponses :
Vérifiez le type de l'objet renvoyé par des tableaux.Aslist appel. Je voudrais devinez em> il renvoie une liste
Regardez la nouvelle ligne que je viens de poster. Et pourquoi est-ce non castable?
Tout se résume à ce que j'ai commenté la réponse de Grzegorzoledzki. Les références vous permettraient d'utiliser une gamme de classes plus large que votre classe de génériques d'origine accepte.
Peut-être que cela vous aiderait à comprendre: ceci ne compile pas non plus avec une erreur similaire. p> EDIT:
Consultez:
http://www.ibm.com/developerworks/java/library/ j-jtp01255.html p> p>
Cela ne compile pas, car en utilisant la référence Alist, vous seriez capable d'insérer des objets dans votre liste, mais il est censé contenir des cordes uniquement.
Pensez à ce cas d'utilisation. En spécifiant une limite supérieure, vous vous attendez à ce que certaines interfaces minimales soient mises en œuvre. Dis que vous avez un EXTENDE C> CODE> Spécifie les limites supérieures du type, ce qui signifie que le type doit être étendu de C. Extend Object> Code> est apparemment plus général, il est donc incompatible. P>
DOIT () CODE> Méthode déclarée dans C. Toute classe extension C aurait cette méthode mais pas tous les objets d'extension de la classe (c'est chaque classe en Java). P>
Vous avez le mauvais chemin, j'essaie d'assigner s'étend c> à étend l'objet>
Vous devrez peut-être penser à un mauvais moyen :) C'est exactement l'opposé de la sécurité de type d'affectation d'objet.
Ni le travaillerait non plus, si cela a du sens ou non. Les types génériques doivent correspondre exactement, pas seulement en étendant les types.
C'est pire que ça. Vous ne pouvez même pas faire cela:
List<D<? extends C>> a = Arrays.asList(new D<A>(), new D<B>()); //compiles List<D<? extends Object>> b = a; //error
Ceci est fondamentalement le même cas que posté précédent. Fondamentalement, dans un cas de génériques, vous n'êtes jamais autorisé à faire cette décision:
pense à cet exemple: p> ceci ne compile pas car il n'est pas en sécurité . Vous pourriez éventuellement ajouter des chaînes Alist. Vous essayez d'attribuer une liste d'objets qui sont garantis à des chiffres, mais peuvent être n'importe quel numéro, à une liste qui vous garantit uniquement que vous contiendrez des objets, mais qui peuvent être des objets. Si le compilateur a permis ce cas, il desserrerait la restriction sur laquelle les types d'objets sont autorisés à entrer dans la liste. C'est pourquoi vous devez utiliser le caractère générique?, En tant que tel: p> au compilateur Vous avez raison de penser que Votre cas est essentiellement équivalent à p> Vous avez le même problème que ci-dessus, la liste à droite La face ne peut contenir que l'objet de la classe D, dont le paramètre type est C, et vous essayez d'assigner à une liste (du côté gauche) peut contenir des objets de la classe D de la classe D dont le paramètre type peut être n'importe quel objet. P> Donc, si le compilateur a permis à votre code ne serait pas sécurisé et que ce qui suit échouerait. P> arraylist Extend Object> code> signifie "une arracheliste de type spécifique"? " que je ne sais pas, mais que je sais étend votre objet. Cette arrayliste est garantie de ne contenir que des éléments de cet inconnu "?" type, et ne contient donc que des objets ». Dans ce cas, le compilateur ne vous permettra toutefois pas de faire Alist.Ajouter (2). Pourquoi est-ce le cas, car le compilateur ne connaît pas le type des éléments de la liste et que vous ne pouvez pas vous garantir que vous êtes autorisé à insérer des objets entier. P> d Extend Object> Code> est un super-type de d s'étend c> code>. Cependant, liste Liste s'étend d s'étend c >> code>. p> // type parameter of left hand side is ? extends subtype
List<? extends D<? extends Object>> b = Arrays.asList(new D<A>(), new D<B>());
// type parameter of left hand side is identical
List<D<? extends C>> b = Arrays.asList(new D<A>(), new D<B>());
// type parameter of left hand side is ? extends subtype
List<? extends D<? extends C>> c = Arrays.asList(new D<A>());
// type parameter of left hand side is identical
List<D<A>> c = Arrays.asList(new D<A>());
La chose est que althoug this Série d'articles est écrit pour la plate-forme .NET La description du problème est toujours vraie pour Java Generics P> list liste liste list
Vous devez échapper à ces supports d'angle avec des backticks.
Vous ne pouvez pas hériter dans le paramètre générique. Dites que vous avez suivi des références suivantes: Vous affectez maintenant la même liste: A = B; p> Si un code est le suivant: P> String s = b.get(0);
Nope.
s'étend c> n'est pas la même chose que étend l'objet>
Si c'était le cas, cela mènerait également l'hypothèse (non déclarée) - C étend un objet, et conduisait à dire ... p>
Classe C {Public Void DosomethermandeDentillante (); }; p>
liste s'étend C> AllatSea = New ArrayList <...> ();
Liste Extend Object> Allobjects = New ArrayList <...> ();
allObject.add (nouveau entier (88));
... p>
AllatSea.addall (Allobjects);
... p>
AllatSea.get (...). Dosomethingmaningful (...);
// uh-oh .. cela trouve l'entier 88 P>
code> Le C ++ FAQ fournit un exemple lucide pour cela à 21,3 p> p>
p>
Je ne pense pas qu'un exemple C ++ aide dans une question Java.
Je vous prie de différer, si la liste est la même que la liste de quelque chose - d'autre concerne la compréhension de l'héritage et la substituabilité.
que, imo, concerne les fondements OO; Par conséquent, la référence à C ++ devrait être acceptable
L'exemple n'est toujours pas correct (ou même aide, imo). La ligne ALTATEA.ADDALL () ne compile pas, et l'AllObject.Ajoud ().
Je pense que cela sera plus clair si nous étendons votre exemple. Mettons des fonctionnalités dans e et élaborer sur la première ligne de votre méthode principale: La dernière ligne de la nouvelle méthode principale est la raison pour laquelle A1 ne peut pas être réglé sur A2. Si le compilateur vous laissait faire cela, vous seriez peut-être en mesure de mettre un d dans un conteneur qui a été déclaré ne contenant que d s. P> La raison en n'est pas évidente de Votre exemple original est dû au fait que vous n'avez pas créé une variable distincte qui a référencé l'objet à l'aide de la typographie plus restrictive E
Lorsque vous attribuez à une variable ( Ce que vous pouvez faire, car E t code>, l'objet étant attribué doit avoir exactement t code> comme type générique (y compris tous les paramètres de type générique de T code>, wildcard et non générique). Dans votre cas t code> est d code>, qui n'a pas le même type que d ? Étend c> code>. d code> est assignable à d Étend C> code>, utilise le type WildCard: P> E<? extends D<? extends C>> a = new E<D<A>();
Je pense que cette réponse explique le meilleur de tous. Vous pouvez faire e s'étend e
C'est une bonne question pour la prochaine édition de Java Puzzlers Javapuzzlers.com
Je crois que tu es tombé sur un cas de bord. Très intéressant.
Cela peut être utile si vous pouvez avoir une idée de cela: bit.ly/3rrnv3