J'essaie d'apprendre les génériques Java. Je ne sais pas quand vous utiliserez <T extends Foo>
et quand vous utiliserez <T super Foo>
. Que signifie chacune de ces choses à propos de T? Disons que j'ai <T extends Comparable>
et <T super Comparable>
, qu'est-ce que cela signifie?
J'ai lu plusieurs tutoriels sur Sun.com mais je suis toujours perdu. Quelqu'un peut-il illustrer avec des exemples?
Merci!
Voir Effective Java 2nd Edition, Item 28:
PECS
P roducteur e xtends, C onsumer - s supérieur
Si votre paramètre est un producteur, il doit être <? extends T>
, s'il s'agit d'un consommateur, il doit être <? super T>
.
Jetez un œil aux collections Google, ils savent comment l'utiliser, car ils ont obtenu Bloch;)
Cela dépend de la manière dont il autorise la hiérarchie d'héritage. Supposons que vous ayez une classe "Child" qui hérite de "Parent" qui hérite de "Grandparent".
<T extends Parent>
accepte parent ou enfant pendant que <T super Parent>
accepte parent ou grand-parent.
Il existe trois types de caractères génériques:
? extends Type
: Désigne une famille de sous-types de type Type
. Il s'agit du caractère générique le plus utile.? super Type
: Désigne une famille de supertypes de type Type
.?
: Indique l'ensemble de tous les types ou de tout type.Pour moi, la meilleure réponse est venue de @BSingh, quand j'ai lu l'article de l'oncle Bob. Je reprends ici, la conclusion de l'article.
Utilisez List <T super Suit> chaque fois que vous allez écrire dans la liste.
Lorsque vous mettez un objet dans la liste, tout ce qui vous importe, c'est que l'objet est d'un type compatible avec le type contenu dans la liste. Vous voulez donc que la liste prenne le type de cet objet ou l'une des superclasses de cet objet.
Utilisez Liste <T étend Suit> chaque fois que vous allez lire dans une liste.
D'un autre côté, lorsque vous lisez à partir d'une liste, vous voulez que le type que vous lisez soit le type contenu par la liste, ou un dérivé de ce type.
Si vous demandez des paramètres de type, il n'y a pas de <T super X>
construire en Java. Le paramètre délimité ne peut que extend
, mais il peut étendre plusieurs types. Par exemple
public class MyClass< T extends Closeable & Runnable >
{
// Closeable and Runnable are chosen for demonstration purposes only
}
Dans ce cas, si vous voyez MyClass< ConcreteT >
alors ConcreteT doit être déclaré comme
public class ConcreteT
implements Closeable, Runnable
{
...
}
Pour les caractères génériques bornés, lisez cet article . Lisez la section sur le principe du get-put . Fondamentalement, super
correspond à la sémantique write
et extends
correspond à la sémantique read
.
N'oubliez pas PECS - Le producteur étend son assistance aux consommateurs. De plus, l'oncle Bob en parle bien dans sa série d'artisans. Découvrez http://objectmentor.com/resources/articles/The_Craftsman_44__Brown_Bag_I.pdf