在 Java 代码片段中:
SyndFeedInput fr = new SyndFeedInput(); SyndFeed sf = fr.build(new XmlReader(myInputStream)); List<SyndEntry> entries = sf.getEntries();
最后一行生成警告
List类型的表达式需要未检查的转换以符合 List<SyndEntry>
List
List<SyndEntry>
有什么合适的方法来解决这个问题呢?
SyndFeed是你写的吗?
SyndFeed
sf.getEntries返回列表还是 List<SyndEntry>?我的猜测是,它返回 List并将其更改为返回 List<SyndEntry>将解决这个问题。
sf.getEntries
如果 SyndFeed是库的一部分,我不认为您可以在不向您的方法添加 @SuppressWarning("unchecked")注释的情况下删除这个警告。
@SuppressWarning("unchecked")
如果在 javadoc 中查找类 SyndFeed(我猜您指的是类 com.sun.syndication.feed.synd.SyndFeed) ,那么 getEntry ()方法不返回 java.util.List<SyndEntry>,而只返回 java.util.List。
com.sun.syndication.feed.synd.SyndFeed
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,所以它可以容纳任何东西。
getEntries
无警告的方法是创建一个新的 List<SyndEntry>,然后在将 sf.getEntries()结果的每个元素添加到新列表之前将其强制转换为 SyndEntry。Collections.checkedList做 没有做这个检查为你 & mash; 虽然它本来可以实现这样做。
sf.getEntries()
SyndEntry
Collections.checkedList
通过预先进行自己的强制转换,您就“遵守了 Java 泛型的保证条款”: 如果一个 ClassCastException被提出,它将与源代码中的强制转换相关联,而不是与编译器插入的不可见强制转换相关联。
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。
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; }