How do I fix "The expression of type List needs unchecked conversion...'?
Solution 1
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 2
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 3
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
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
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));
Related videos on Youtube
user46277
Updated on November 26, 2021Comments
-
user46277 over 2 years
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 toList<SyndEntry>
"What's an appropriate way to fix this?
-
Uri over 15 yearsYou can also add an explicit cast.
-
brady over 15 yearsA cast will just produce another warning, since the code is not type safe.
-
user46277 over 15 yearsThanks -- that's an interesting insight about the "warranty" and the invisible cast done by the compiler versus a cast done explicitly in my own code.
-
brady over 15 yearsYes, the value of un-reified generics is somewhat limited, but that is one thing it does provide. Just to clarify, this requires that your code compiles without type safety warnings.
-
Bruno De Fraine almost 14 yearsHi erickson, I agree that this indeed the best solution. Check my answer stackoverflow.com/questions/367626/… for a generic version of this solution.
-
will824 about 13 yearsRegarding the method suggested by Bruno, Wouldnt this hurt application performance when having Lists with many elements?. Java would have to cast each and every one of them.
-
ingyhere about 11 yearsThen you would deal with proper casting (re-casting?) at usage time for each element in ArrayList<?>.
-
Dan Rosenstark almost 10 yearsSince they both suppress the warning, any advantages to one or the other, or a preference? Thanks! Also: is the cast necessary if the unchecked suppression is in place?
-
Jon Skeet almost 10 years@Yar: Well,
Collections.checkedList
will prevent the addition of any non-SyndEntry elements later. I personally don't usecheckedList
much, but then I also don't often get into this unchecked cast situation anyway... -
sbrattla almost 9 yearsEven if the code provided here solves the problem, i'd encourage you to briefly explain why it does that. Please explain why the posted answer solves the issue.
-
dan almost 7 yearsIf you want guarantees, that is the cost. Is there another less expensive option? Obviously, if you have control over the invoked raw collection returning method, or even invoking the method or accessing the collection using a lazy-demand approach. Anything that considers the entire collection after the method invocation?
-
brettv over 6 years
SyndFeed
comes from rometools.github.io/rome/ROMEReleases/ROME1.0Release.html. The problem seems to be fixed in more recent versions of Rome like the ones found at mvnrepository.com/artifact/com.rometools/rome/1.9.0