Il s'agit d'une version simplifiée du code en question, une classe générique utilise une autre classe avec des paramètres de type générique et doit passer l'un des types génériques à une méthode avec des paramètres varargs:
class Assembler<X, Y> {
void assemble(X container, Y... args) { ... }
}
class Component<T> {
void useAssembler(T something) {
Assembler<String, T> assembler = new Assembler<String, T>();
//generates warning:
// Type safety : A generic array of T is
// created for a varargs parameter
assembler.assemble("hello", something);
}
}
Existe-t-il un moyen correct de transmettre le paramètre générique à une méthode varargs sans rencontrer cet avertissement?
Bien sûr, quelque chose comme
assembler.assemble("hello", new T[] { something });
ne fonctionne pas car vous ne pouvez pas créer de tableaux génériques.
Réponses:
À part ajouter
@SuppressWarnings("unchecked")
, je ne pense pas.Ce rapport de bogue contient plus d'informations, mais il se résume au fait que le compilateur n'aime pas les tableaux de types génériques.
la source
Tom Hawtin l'a souligné dans un commentaire, mais pour être plus explicite: oui, vous pouvez résoudre cela sur le site de déclaration (plutôt que sur les (potentiellement nombreux) sites d'appel): passez à JDK7.
Comme vous pouvez le voir dans l'article de blog de Joseph Darcy , l'exercice Project Coin pour sélectionner de petites améliorations progressives du langage pour Java 7 a accepté la proposition de Bob Lee d'autoriser quelque chose comme
@SuppressWarnings("varargs")
du côté de la méthode pour faire disparaître cet avertissement dans des situations où il était connu sûr.Cela a été implémenté dans OpenJDK avec ce commit .
Cela peut être utile ou non pour votre projet (beaucoup de gens ne seraient pas heureux de passer à une version instable de pré-version de la JVM!) Mais peut-être que c'est - ou peut-être quelqu'un qui trouvera cette question plus tard (après la sortie de JDK7 ) le trouvera utile.
la source
Si vous recherchez une interface de type fluide, vous pouvez essayer le modèle de générateur. Pas aussi concis que varargs mais il est de type sûr.
Une méthode statique de type générique peut éliminer une partie du passe-partout lors de l'utilisation du constructeur, tout en conservant la sécurité de type.
Le constructeur
En l'utilisant
la source
Collection
(dans ce cas, unArrayList
) est forcé sur l'appelant, alors qu'ils peuvent savoir que aLinkedList
est plus approprié, ou un tableau immuable lui-même (comme les varargs de la question OP). Dans un cas d'utilisation non spécialisé, cela peut être approprié, mais il suffit de souligner que c'est aussi une limitation, d'une certaine manière, en fonction du code qui l'entoure et de vos besoins.Le cast explicite des paramètres en Object dans l'invocation de la méthode vararg rendra le compilateur heureux sans recourir à @SuppressWarnings.
Je crois que le problème ici est que le compilateur doit déterminer quel type concret de tableau créer. Si la méthode n'est pas générique, le compilateur peut utiliser les informations de type de la méthode. Si la méthode est générique, elle essaie de déterminer le type de tableau en fonction des paramètres utilisés lors de l'appel. Si les types de paramètres sont homogènes, cette tâche est facile. S'ils varient, le compilateur essaie d'être trop intelligent à mon avis et crée un tableau générique de type union. Ensuite, il se sent obligé de vous en avertir. Une solution plus simple aurait été de créer Object [] lorsque le type ne peut pas être mieux réduit. La solution ci-dessus impose justement cela.
Pour mieux comprendre cela, jouez avec les appels à la méthode list ci-dessus par rapport à la méthode list2 suivante.
la source
Vous pouvez ajouter @SafeVarargs à la méthode depuis Java 7, et vous n'avez pas à annoter sur le code client.
la source
Vous pouvez surcharger les méthodes. Cela ne résout pas votre problème mais cela minimise le nombre d'avertissements (et oui, c'est un hack!)
la source
C'est un problème très facile à résoudre: utilisez
List<T>
!Les tableaux de type référence doivent être évités.
Dans la version actuelle de Java (1.7), vous pouvez marquer la méthode avec
@SafeVargs
laquelle supprimera l'avertissement de l'appelant. Attention cependant, et vous êtes toujours mieux sans les baies héritées.Consultez également la note technique Avertissements et erreurs du compilateur améliorés lors de l'utilisation de paramètres formels non réifiables avec les méthodes Varargs .
la source
Lorsque je travaille avec des tableaux de type générique, je suis obligé de passer une référence au type générique. Avec cela, je peux réellement faire le code générique, en utilisant java.lang.reflect.Array.
http://java.sun.com/javase/6/docs/api/java/lang/reflect/Array.html
la source