9
votes

Générations de fantaisie Capturez la collision

S'il vous plaît donnez-moi un indice quant à ce qui se passe ici: xxx

Ce code simple ne compile pas. Je me souviens vaguement de quelque chose lié aux captures de type, comme ceux-ci devraient être principalement utilisés dans des spécifications d'interface, pas le code réel, mais je n'ai jamais eu abasourdiné comme ça.

Ceci bien sûr peut être corrigé de manière brutale, comme que: xxx

donc, est-ce que je vraiment abandonner des captures dans la déclaration (la capture m'a été prise d'une interface, donc je "LL doit changer de l'API) ou coller avec des couts de type avec des annotations de suppression (qui suce généralement et complique le code un peu)?


2 commentaires

Bonjour, pourquoi ne pas simplement déclarer A comme list a = nouvelle arrayliste () ?


Eh bien, j'ai déjà une API qui déclare déjà cette capture lors de la retournement d'une liste. J'utilise un constructeur juste pour garder les choses plus simples tout en leur rendant un peu plus obscur (sans réserve).


5 Réponses :


11
votes

Vous avez essentiellement deux listes de types éventuellement différents. Parce que ? Étend le numéro signifie une classe qui s'étend numéro . Donc, pour la liste a il peut être classa et pour la liste b il peut être par exemple classb . Ils ne sont pas compatibles, ils peuvent être totalement différents.


6 commentaires

Vous êtes méchant ... fournir un commentaire comme un leurre. Je voulais répondre à ce commentaire avant de répondre. Maintenant, le commentaire est parti et vous avez répondu à la place. ;)


@Musikk - hahahaha, tout était prévu;)


Ceci est en quelque sorte lié à la covariance de type. Peut-être que l'exemple lui-même (Addall Operation) est un peu restrictif, mais mon opinion est que je devrais pouvoir effectuer toutes les opérations de collecte aussi longtemps que des égaux () et HashCode () sont définis sur les objets qui sont dans la collection. upd : et, en fait, Java est également restrictif à cet égard: je suis incapable de créer directement une base générale: nouvelle arraylist (); // Aie!..


... Tant que les égaux () et HashCode () sont définis sur les objets qui sont dans la collection ... Notez que les listes n'utilisent pas ces méthodes du tout. De plus, les génériques ne sont pas seulement des collections et il n'y a aucune distinction entre les différentes utilisations de ces caractères génériques (à compter du type de classe générique ou quel type de collection que vous avez) - au moins encore.


Java est également restrictif à cet égard: je suis incapable de créer directement une base générale: nouvelle arrayliste (); Pourquoi voudriez-vous faire cela? Tout ce que vous avez besoin de savoir est que le tableau détient des objets de numéro de type et donc nouvelle arraylist (); doit être utilisé. Si vous pouviez utiliser la notation ? , vous devez toujours vérifier le type de chaque élément. Et qu'est-ce que le ? réellement signifie? - "Vous pouvez mettre n'importe quel objet qui est de type numéro ou une sous-classe dans cette liste", ce qui correspond exactement au même sens que nouvelle arrayliste (); .


Eh bien, Addall () n'utilisera pas d'équivalents (), tandis que RemoveAll () serait. Je pensais juste à quelles opérations nous devons appuyer pour garder cette liste de travail. Toutes vos remarques sont parfaitement correctes et utiles. Merci.



7
votes

Le problème est que si vous utilisez la liste Étend Numéro> Code> Vous pouvez réellement faire:

List<Number> c = new ArrayList<Number>(a.size() + b.size());
c.addAll(a);
c.addAll(b);


2 commentaires

Uhm ... le code de contournement n'était pas correct du tout. L'idée est que j'obtiens deux listes avec une capture, alors j'avais refusé ce code pour refléter l'idée.


Supprimé mon commentaire sur la "solution de contournement" pour éviter toute interprétation erronée



3
votes

N'utilisez pas le ? wildcard. Cela signifie "un type spécifique que je ne sais pas" et que vous ne connaissez pas le type, vous ne pouvez rien ajouter à la liste. Changez votre code pour utiliser Liste et tout fonctionnera.

Cela devient rapide de la question de Java la plus fréquemment posée, dans une centaine de variations ...


2 commentaires

Ok, d'accord, mais quels sont les guides généraux d'utiliser des caractères génériques du tout?


@Anton: Regardez ici une explication plus profonde avec des exemples: angélikalanger.com/genericsfaq/faqsections/... ? Mais en général, les caractères génériques ne sont utiles que dans quelques rares cas.



1
votes

La chose est: xxx

pourrait également être lue comme: xxx

Comment le compilateur devrait-il savoir que x et y sont la même?


1 commentaires

Eh bien, j'étais sûr que le compilateur ait toutes les informations dont il a besoin. Pas le cas... :)



2
votes

pecs (producteur-étend, consommateur-super)

  • Vous ne pouvez rien mettre dans un type déclaré avec une étendue générique Sauf pour la valeur null, qui appartient à chaque type de référence
  • Vous ne pouvez rien obtenir d'un type déclaré avec un super Wildcard sauf pour une valeur d'objet de type, qui est un type super de chaque type de référence

0 commentaires