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

在 Java 代码片段中:

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

最后一行生成警告

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

有什么合适的方法来解决这个问题呢?

229633 次浏览

SyndFeed是你写的吗?

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

如果 SyndFeed是库的一部分,我不认为您可以在不向您的方法添加 @SuppressWarning("unchecked")注释的情况下删除这个警告。

如果在 javadoc 中查找类 SyndFeed(我猜您指的是类 com.sun.syndication.feed.synd.SyndFeed) ,那么 getEntry ()方法不返回 java.util.List<SyndEntry>,而只返回 java.util.List

所以你需要一个明确的强制类型转换。

看起来 SyndFeed没有使用泛型。

您可以选择不安全的强制转换和警告抑制:

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

或者打电话给 Collections.checkedList——尽管你仍然需要压制这个警告:

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

因为 getEntries返回一个原始的 List,所以它可以容纳任何东西。

无警告的方法是创建一个新的 List<SyndEntry>,然后在将 sf.getEntries()结果的每个元素添加到新列表之前将其强制转换为 SyndEntryCollections.checkedList没有做这个检查为你 & mash; 虽然它本来可以实现这样做。

通过预先进行自己的强制转换,您就“遵守了 Java 泛型的保证条款”: 如果一个 ClassCastException被提出,它将与源代码中的强制转换相关联,而不是与编译器插入的不可见强制转换相关联。

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

参见 另一个问题

在处理 Java5API 之前的 API 时,这是一个常见问题。要使 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

更简单

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

如果您正在使用 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));
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<?> entries = sf.getEntries();

布鲁诺 · 德 · 弗雷恩的回答很棒。但是,如果输入参数的大小为“ Collection < ? ? > “ c”是0,然后例程崩溃与空指针。 为了避免这种情况,我建议做一个小小的改进(我给出了 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;
}