J'ai un conteneur (liste) de certains éléments de type T et souhaitez le filtrer. Donc, il ne contient que des éléments d'un sous-type spécifique U. Serait-il possible de définir un type de retour «dynamique»?
Exemple: P>
Note: SomeContainer.java uses unchecked or unsafe operations. Note: Recompile with -Xlint:unchecked for details.
3 Réponses :
java.lang.class Code> est un type générique paramétré sur lui-même. Vous pouvez donc utiliser son paramètre de type, comme celui-ci:
public <U extends T> SomeContainer<U> subset(Class<U> c){
SomeContainer<U> output = new SomeContainer<U>();
for (T val : this) {
if (c.isInstance(val)) {
output.add(c.cast(val));
}
}
return output;
}
Ou mieux, Sortie.Ajouter (C.Cast (Val)) Code> Pour éviter l'avertissement non coché.
@ Bianroberts absolument! Merci pour une bonne suggestion!
Les génériques sont un artefact de la compilation uniquement, votre schéma ne peut donc pas fonctionner. Le compilateur ne peut pas prédire quelle classe vous souhaiterez à chaque exécution de la ligne de code qui appelle à cette fonction. Vous ne pouvez pas faire de cette solution de type-coffre-fort
Premier point: vous pouvez supprimer l'avertissement de fonctionnement non coché en remplaçant l'argument second point:
Habituellement, le code appelant Somecontainer.Subset () Sachez à la compilation Tapez le type U (dans le contexte logique). Cela doit être le cas pour vous, sinon vous ne seriez pas en mesure de transmettre l'argument code> Classe C code> dans. P> Essayez: p> Classe C code> avec Classe public SomeContainer<? extends X> subset(Class<? extends X> c){
SomeContainer<? extends X> output = null;
// would like to use: "if (c instance of Class<Z>)"
// but instanceof does not allow generic type arguments
if (c.getName().equals(Z.class.getName())) {
SomeContainer<Z> outputZ = new SomeContainer<Z>();
// put filtered elements into outputZ
output = outputZ;
} else if (c.getName().equals(Y.class.getName())) {
SomeContainer<Y> outputY = new SomeContainer<Y>();
// put filtered elements into outputZ
output = outputY;
} else if (c.getName().equals(X.class.getName())) {
SomeContainer<X> outputX = new SomeContainer<X>();
// put filtered elements into outputZ
output = outputX;
}
return output;
}
L'avertissement est parce que vous utilisez
classe code> au lieu de la classe> Code>. Et je ne suis pas sûr que vous puissiez utiliser des types dynamiques dans des paramètres de modèle.Il ne contient donc que des éléments d'un sous-type spécifique u i> Pourquoi ne pas déclarer avec ce sous-type spécifique u?