在 Java 代码段中:
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<SyndEntry> entries = sf.getEntries();
最后一行生成警告
“类型的表达List
需要未经检查的转换才能符合List<SyndEntry>
”
解决此问题的适当方法是什么?
在 Java 代码段中:
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<SyndEntry> entries = sf.getEntries();
最后一行生成警告
“类型的表达List
需要未经检查的转换才能符合List<SyndEntry>
”
解决此问题的适当方法是什么?
这是处理 Java 5 之前的 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
.
由于getEntries
返回一个 raw List
,它可以容纳任何东西。
无警告的方法是创建一个新的,然后在将结果的List<SyndEntry>
每个元素添加到新列表之前将其转换为。不会为您执行此检查 -尽管可以实现它来执行此操作。sf.getEntries()
SyndEntry
Collections.checkedList
通过预先进行自己的转换,您“遵守了 Java 泛型的保证条款”:如果ClassCastException
引发 a,它将与源代码中的转换相关联,而不是编译器插入的不可见转换。
看起来SyndFeed
没有使用泛型。
你可以有一个不安全的演员和一个警告抑制:
@SuppressWarnings("unchecked")
List<SyndEntry> entries = (List<SyndEntry>) sf.getEntries();
或致电Collections.checkedList - 尽管您仍然需要禁止显示警告:
@SuppressWarnings("unchecked")
List<SyndEntry> entries = Collections.checkedList(sf.getEntries(), SyndEntry.class);
你写了SyndFeed
吗?
是否sf.getEntries
返回 List 或List<SyndEntry>
? 我的猜测是它返回List
并将其更改为返回List<SyndEntry>
将解决问题。
如果SyndFeed
是库的一部分,我认为您不能在不向@SuppressWarning("unchecked")
您的方法添加注释的情况下删除警告。
如果您正在使用 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));
如果您查看该类的 javadoc SyndFeed
(我猜您指的是该类com.sun.syndication.feed.synd.SyndFeed
),则 getEntries() 方法不会返回java.util.List<SyndEntry>
,而是仅返回java.util.List
.
所以你需要一个明确的演员表。
SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<?> entries = sf.getEntries();
如果您不想在每个 sf.getEntries() 调用上放置 @SuppressWarning("unchecked"),您始终可以创建一个将返回 List 的包装器。
看到这个另一个问题
更容易
return new ArrayList<?>(getResultOfHibernateCallback(...))
Bruno De Fraine 的回答很棒。但是,如果输入参数“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;
}