How do I fix "The expression of type List needs unchecked conversion...'?

218,211

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));
Share:
218,211

Related videos on Youtube

user46277
Author by

user46277

Updated on November 26, 2021

Comments

  • user46277
    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 to List<SyndEntry>"

    What's an appropriate way to fix this?

  • Uri
    Uri over 15 years
    You can also add an explicit cast.
  • brady
    brady over 15 years
    A cast will just produce another warning, since the code is not type safe.
  • user46277
    user46277 over 15 years
    Thanks -- 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
    brady over 15 years
    Yes, 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
    Bruno De Fraine almost 14 years
    Hi erickson, I agree that this indeed the best solution. Check my answer stackoverflow.com/questions/367626/… for a generic version of this solution.
  • will824
    will824 about 13 years
    Regarding 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
    ingyhere about 11 years
    Then you would deal with proper casting (re-casting?) at usage time for each element in ArrayList<?>.
  • Dan Rosenstark
    Dan Rosenstark almost 10 years
    Since 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
    Jon Skeet almost 10 years
    @Yar: Well, Collections.checkedList will prevent the addition of any non-SyndEntry elements later. I personally don't use checkedList much, but then I also don't often get into this unchecked cast situation anyway...
  • sbrattla
    sbrattla almost 9 years
    Even 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
    dan almost 7 years
    If 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
    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