Dans l'extrait Java:
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<SyndEntry> entries = sf.getEntries();
la dernière ligne génère l'avertissement
"L’expression de type List
nécessite une conversion non contrôlée pour se conformer à List<SyndEntry>
"
Quel est un moyen approprié pour résoudre ce problème?
Puisque getEntries
renvoie un List
brut, il peut contenir n'importe quoi.
L'approche sans avertissement consiste à créer un nouveau List<SyndEntry>
, Puis convertissez chaque élément du résultat sf.getEntries()
en SyndEntry
avant de l'ajouter à votre nouvelle liste. Collections.checkedList
Fait pas effectue cette vérification pour vous - bien qu'il aurait été possible de l'implémenter pour le faire.
En effectuant votre propre conversion, vous "respectez les conditions de garantie" de Java génériques: si un ClassCastException
est généré, il sera associé à un transfert dans le code source, pas une distribution invisible insérée par le compilateur.
Il s'agit d'un problème courant lorsque vous utilisez des API antérieures à Java 5. Pour automatiser le solution de erickson , vous pouvez créer la méthode générique suivante:
public static <T> List<T> castList(Class<? extends T> clazz, Collection<?> c) {
List<T> r = new ArrayList<T>(c.size());
for(Object o: c)
r.add(clazz.cast(o));
return r;
}
Cela vous permet de faire:
List<SyndEntry> entries = castList(SyndEntry.class, sf.getEntries());
Comme cette solution vérifie que les éléments ont bien le bon type d’élément au moyen d’un transtypage, elle est sûre et ne nécessite pas SuppressWarnings
.
Il semble que SyndFeed
n'utilise pas de génériques.
Vous pouvez avoir une conversion non sécurisée et une suppression d'avertissement:
@SuppressWarnings("unchecked")
List<SyndEntry> entries = (List<SyndEntry>) sf.getEntries();
ou appelez Collections.checkedList - bien que vous ayez toujours besoin de supprimer l'avertissement:
@SuppressWarnings("unchecked")
List<SyndEntry> entries = Collections.checkedList(sf.getEntries(), SyndEntry.class);
Avez-vous écrit le SyndFeed
?
Est-ce que sf.getEntries
Renvoie la liste ou List<SyndEntry>
? Je suppose que cela retourne List
et que le changer pour retourner List<SyndEntry>
Résoudra le problème.
Si SyndFeed
fait partie d'une bibliothèque, je ne pense pas que vous puissiez supprimer l'avertissement sans ajouter l'annotation @SuppressWarning("unchecked")
à votre méthode.
Si vous utilisez Guava et que vous ne voulez que faire, parcourez vos valeurs:
for(SyndEntry entry: Iterables.filter(sf.getEntries(), SyndEntry.class){
...
}
Si vous avez besoin d’une liste réelle, vous pouvez utiliser
List<SyndEntry> list = Lists.newArrayList(
Iterables.filter(sf.getEntries(), SyndEntry.class));
ou
List<SyndEntry> list = ImmutableList.copyOf(
Iterables.filter(sf.getEntries(), SyndEntry.class));
Si vous regardez le javadoc pour la classe SyndFeed
(je suppose que vous faites référence à la classe com.Sun.syndication.feed.synd.SyndFeed
), la méthode getEntries () ne renvoie pas Java.util.List<SyndEntry>
, mais retourne juste Java.util.List
.
Donc, vous avez besoin d'un casting explicite pour cela.
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<?> entries = sf.getEntries();
Si vous ne voulez pas mettre @SuppressWarning ("décoché") sur chaque appel sf.getEntries (), vous pouvez toujours créer un wrapper qui retournera List.
Voir cette autre question
Encore plus facile
return new ArrayList<?>(getResultOfHibernateCallback(...))