Answers:
由于getEntries
返回原始List
,因此可以容纳任何内容。
无警告的方法是创建一个new List<SyndEntry>
,然后将sf.getEntries()
结果的每个元素强制转换为,然后再将其SyndEntry
添加到新列表中。Collections.checkedList
并没有做这个检查你-虽然它本来可以实现它这样做。
通过ClassCastException
预先进行自己的转换,您将“遵守Java泛型的保修条款”:如果将a 引发,它将与源代码中的转换相关联,而不是与编译器插入的不可见转换相关联。
在处理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
。
看起来像 SyndFeed
没有使用泛型。
您可能有不安全的演员表和警告提示:
@SuppressWarnings("unchecked")
List<SyndEntry> entries = (List<SyndEntry>) sf.getEntries();
或致电Collections.checkedList-尽管您仍然需要取消显示警告:
@SuppressWarnings("unchecked")
List<SyndEntry> entries = Collections.checkedList(sf.getEntries(), SyndEntry.class);
Collections.checkedList
稍后将阻止添加任何非SyndEntry元素。我个人并没有使用checkedList
太多,但是无论如何我也很少遇到这种不受限制的情况……
你写了SyndFeed
吗?
是否sf.getEntries
返回List或List<SyndEntry>
?我的猜测是返回List
,将其更改为return List<SyndEntry>
将解决此问题。
如果SyndFeed
是库的一部分,我认为您可以在不向@SuppressWarning("unchecked")
方法中添加注释的情况下删除警告。
SyndFeed
来自rometools.github.io/rome/ROMEReleases/ROME1.0Release.html。这个问题似乎在罗马的最新版本中得到了解决,例如在mvnrepository.com/artifact/com.rometools/rome/1.9.0中
如果您正在使用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();