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

use*_*277 129 java warnings unchecked-conversion

在Java片段中:

SyndFeedInput fr = new SyndFeedInput();
SyndFeed sf = fr.build(new XmlReader(myInputStream));
List<SyndEntry> entries = sf.getEntries();
Run Code Online (Sandbox Code Playgroud)

最后一行生成警告

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

有什么方法可以解决这个问题?

Bru*_*ine 111

在处理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;
}
Run Code Online (Sandbox Code Playgroud)

这允许你这样做:

List<SyndEntry> entries = castList(SyndEntry.class, sf.getEntries());
Run Code Online (Sandbox Code Playgroud)

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

  • 关于Bruno建议的方法,当列出具有许多元素的列表时,这会损害应用程序性能吗?Java必须抛出它们中的每一个. (3认同)
  • 如果你想要保证,那就是成本。还有其他更便宜的选择吗?显然,如果您可以控制调用的原始集合返回方法,或者甚至可以使用延迟需求方法调用该方法或访问集合。任何在方法调用后考虑整个集合的东西? (2认同)

eri*_*son 94

由于getEntries返回原始List,它可以保留任何东西.

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

通过自己的预测,您"遵守Java泛型的保修条款":如果ClassCastException引发了a ,它将与源代码中的强制转换关联,而不是编译器插入的不可见转换.

  • 谢谢 - 这是一个有趣的见解,关于"保修"和编译器完成的隐形转换与我自己的代码中明确完成的转换. (9认同)

Jon*_*eet 25

看起来好像SyndFeed没有使用泛型.

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

@SuppressWarnings("unchecked")
List<SyndEntry> entries = (List<SyndEntry>) sf.getEntries();
Run Code Online (Sandbox Code Playgroud)

或者调用Collections.checkedList - 尽管你仍然需要禁止警告:

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

  • @Yar:好吧,`Collections.checkedList`将阻止以后添加任何非SyndEntry元素.我个人不太多使用`checkedList`,但是我也不经常进入这种未经检查的演员情况...... (2认同)

Ale*_*x B 7

你写过了SyndFeed吗?

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

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

  • 演员阵容只会产生另一个警告,因为代码不是类型安全的. (3认同)