我如何修复“类型列表的表达式需要未经检查的转换...”?

时间:2008-12-15 06:49:11

标签: java warnings unchecked-conversion

在Java代码段中:

SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<SyndEntry> entries = sf.getEntries();

最后一行生成警告

List类型的表达式需要未经检查的转换以符合List<SyndEntry>

解决这个问题的合适方法是什么?

9 个答案:

答案 0 :(得分:111)

在处理Java 5之前的API时,这是一个常见问题。要自动执行solution from erickson,您可以创建以下通用方法:

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;
}

这允许你这样做:

List<SyndEntry> entries = castList(SyndEntry.class, sf.getEntries());

因为此解决方案通过强制转换检查元素确实具有正确的元素类型,所以它是安全的,并且不需要SuppressWarnings

答案 1 :(得分:93)

由于getEntries会返回原始List,因此它可以保留任何内容。

无警告方法是创建新的List<SyndEntry>,然后将sf.getEntries()结果的每个元素投放到SyndEntry,然后再将其添加到新列表中。 Collections.checkedList 为您执行此操作检查 - 尽管可以实现此操作。

通过自己的预测,你“遵守Java泛型的保修条款”:如果引发ClassCastException,它将与源代码中的强制转换相关联,而不是无形的由编译器插入的强制转换。

答案 2 :(得分:25)

看起来SyndFeed没有使用泛型。

您可能有不安全的演员阵容和警告抑制:

@SuppressWarnings("unchecked")
List<SyndEntry> entries = (List<SyndEntry>) sf.getEntries();

或致电Collections.checkedList - 虽然您仍然需要取消警告:

@SuppressWarnings("unchecked")
List<SyndEntry> entries = Collections.checkedList(sf.getEntries(), SyndEntry.class);

答案 3 :(得分:7)

你写过SyndFeed吗?

sf.getEntries会返回列表还是List<SyndEntry>?我的猜测是返回List并将其更改为返回List<SyndEntry>将解决问题。

如果SyndFeed是库的一部分,我认为如果不在方法中添加@SuppressWarning("unchecked")注释,则无法删除警告。

答案 4 :(得分:2)

如果您正在使用Guava,那么您想要做的就是遍历您的值:

for(SyndEntry entry: Iterables.filter(sf.getEntries(), SyndEntry.class){
  ...
}

如果您需要实际的列表,可以使用

List<SyndEntry> list = Lists.newArrayList(
    Iterables.filter(sf.getEntries(), SyndEntry.class));

List<SyndEntry> list = ImmutableList.copyOf(
    Iterables.filter(sf.getEntries(), SyndEntry.class));

答案 5 :(得分:1)

如果查看类SyndFeed的javadoc(我猜你是指类com.sun.syndication.feed.synd.SyndFeed),方法getEntries()不会返回java.util.List<SyndEntry>,而是返回只是java.util.List

所以你需要一个明确的演员。

答案 6 :(得分:1)

SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<?> entries = sf.getEntries();

答案 7 :(得分:0)

如果你不想在每个sf.getEntries()调用上放置@SuppressWarning(“unchecked”),你总是可以创建一个返回List的包装器。

请参阅this other question

答案 8 :(得分:0)

更容易

return new ArrayList<?>(getResultOfHibernateCallback(...))