How do I fix "The expression of type List needs unchecked conversion...'?
JavaWarningsUnchecked ConversionJava Problem Overview
In the Java snippet:
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<SyndEntry> entries = sf.getEntries();
the last line generates the warning
"The expression of type List
needs unchecked conversion to conform to List<SyndEntry>
"
What's an appropriate way to fix this?
Java Solutions
Solution 1 - Java
This is a common problem when dealing with pre-Java 5 APIs. To automate the solution from erickson, you can create the following generic method:
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;
}
This allows you to do:
List<SyndEntry> entries = castList(SyndEntry.class, sf.getEntries());
Because this solution checks that the elements indeed have the correct element type by means of a cast, it is safe, and does not require SuppressWarnings
.
Solution 2 - Java
Since getEntries
returns a raw List
, it could hold anything.
The warning-free approach is to create a new List<SyndEntry>
, then cast each element of the sf.getEntries()
result to SyndEntry
before adding it to your new list. Collections.checkedList
does not do this checking for you—although it would have been possible to implement it to do so.
By doing your own cast up front, you're "complying with the warranty terms" of Java generics: if a ClassCastException
is raised, it will be associated with a cast in the source code, not an invisible cast inserted by the compiler.
Solution 3 - Java
It looks like SyndFeed
is not using generics.
You could either have an unsafe cast and a warning suppression:
@SuppressWarnings("unchecked")
List<SyndEntry> entries = (List<SyndEntry>) sf.getEntries();
or call Collections.checkedList - although you'll still need to suppress the warning:
@SuppressWarnings("unchecked")
List<SyndEntry> entries = Collections.checkedList(sf.getEntries(), SyndEntry.class);
Solution 4 - Java
Did you write the SyndFeed
?
Does sf.getEntries
return List or List<SyndEntry>
? My guess is it returns List
and changing it to return List<SyndEntry>
will fix the problem.
If SyndFeed
is part of a library, I don't think you can remove the warning without adding the @SuppressWarning("unchecked")
annotation to your method.
Solution 5 - Java
If you are using Guava and all you want to do is iterate through your values:
for(SyndEntry entry: Iterables.filter(sf.getEntries(), SyndEntry.class){
...
}
If you need an actual List you can use
List<SyndEntry> list = Lists.newArrayList(
Iterables.filter(sf.getEntries(), SyndEntry.class));
or
List<SyndEntry> list = ImmutableList.copyOf(
Iterables.filter(sf.getEntries(), SyndEntry.class));
Solution 6 - Java
If you look at the javadoc for the class SyndFeed
(I guess you are referring to the class com.sun.syndication.feed.synd.SyndFeed
), the method getEntries() doesn't return java.util.List<SyndEntry>
, but returns just java.util.List
.
So you need an explicit cast for this.
Solution 7 - Java
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<?> entries = sf.getEntries();
Solution 8 - Java
If you don't want to put @SuppressWarning("unchecked") on each sf.getEntries() call, you can always make a wrapper that will return List
Solution 9 - Java
Even easier
return new ArrayList<?>(getResultOfHibernateCallback(...))
Solution 10 - Java
The answer of Bruno De Fraine is great. However if the size of input argument "Collection c" is 0 then the routine crashes with null pointer. I suggest a minor improvement to avoid this (and I give the version for HashSet):
public static <T> HashSet<T> castHashSet(Class<? extends T> clazz, Collection<?> c) {
int cSize = (c == null) ? 0 : c.size();
HashSet<T> hashSet = new HashSet<T>(cSize);
if (c != null) {
for (Object o : c)
hashSet.add(clazz.cast(o));
}
return hashSet;
}