todd.run est totalement à droite, mais ce n'est que la moitié de la réponse. Il existe également des cas d'utilisation pour choisir <T>
sur <?>
(ou vice versa) qui s'appliquent lorsque vous n'ajoutez pas de paramètre de type à la classe qui contient la méthode. Par exemple, considérez la différence entre
public <E extends JLabel> boolean add(List<E> j) {
boolean t = true;
for (JLabel b : j) {
if (b instanceof JLabel) {
t = t && labels.add(b);
}
}
return t;
}
et
public boolean add(List<? extends JLabel> j) {
boolean t = true;
for (JLabel b : j) {
if (b instanceof JLabel) {
t = t && labels.add(b);
}
}
return t;
}
La première méthode fait pas compiler SAUF si vous ajoutez un paramètre de type approprié à la classe englobante, tandis que la seconde méthode compilerons indépendamment du fait que la classe englobante a un paramètre de type. Si vous n'utilisez pas <?>
, alors vous êtes localement responsable de dire au compilateur comment acquérir le type qui sera rempli par la lettre utilisée à sa place. Vous rencontrez fréquemment ce problème - besoin d'utiliser? plutôt que T - lorsque vous essayez d'écrire des méthodes génériques qui utilisent ou nécessitent "étend" et "super". Un traitement meilleur mais plus élaboré de ce problème est à la page 18 de Gilad Bracha's Generics Tutorial (PDF). Voir aussi this stack overflow question dont la réponse éclaire ces problèmes.
Consultez ce lien de débordement de pile pour plus d'informations sur votre deuxième question: Java generics - type erasure - when and what happens. Bien que je ne connais pas la réponse à votre question sur la différence de temps de compilation entre <?>
et <T>
, je suis assez sûr que la réponse peut être trouvée à this FAQ que erickson mentionné dans ce post.
Vous pouvez capturer le type générique dans ce cas: boolean add (liste Extends JLabel> list) {return addImpl (list); } boolean addImpl (Liste list) {... –
(L'exemple de code est un peu étrange Vous pourriez revenir après que labels.add retourne false –
Cette réponse n'a pas de sens et n'est pas correcte. Je mets la première méthode dans une classe sans paramètre de type ('public class test {Liste labels = new ArrayList (); // ajoute la méthode ici}') et compile bien. –
user102008