1

考虑你有这个列表:

private final List<? extends AbstractXmlElement> inMemoryElements;

它包含一堆 AbstractXmlElement 子类的对象,并且您想要添加一个方法来从该列表中过滤特定子类的对象。为此,我创建了以下方法:

public <E extends AbstractXmlElement> List<E> getInstancesOf(Class<E> c) {
    return getUsableElements().stream()
        .filter(c::isInstance)
        .map(e -> (E) e)
        .collect(Collectors.toList());
}

然而 (E) e 导致 UncheckedCast 警告。我想知道这究竟是一个未经检查的强制转换,以及抑制这个警告是否安全,因为那些不是 E 实例的对象在强制转换之前被过滤掉了。这意味着,据我所知,演员阵容永远不应该失败

4

2 回答 2

3

这是一个未经检查的强制转换,因为在运行时类型E未知的。由于您正在检查isInstance(),因此您的代码是安全的。但是如果你想避免警告,你可以使用c做演员:

.map(c::cast)
于 2018-07-30T19:44:11.280 回答
2

这是一个未经检查的演员表

您唯一的保证是这eAbstractXmlElement. 但它可以是任何子类。因此,如果您有一个子类A并且B都扩展AbstractXmlElement了 ,理论上类型约束意味着您可以尝试强制A转换为B,如果您B.class作为参数传递并且您的集合包含A. 因此发出警告。

请注意,编译器不会检查您的过滤器表达式以找出只有 的实例E才能使其通过过滤器;特别是它不会去阅读文档,然后还假设文档是正确的。据它所知,c::isInstance()这只是另一种采用 aObject并返回 a 的随机方法boolean。在这一点上,没有任何迹象表明只有E在经过过滤器的流中保留的实例。

如果可以安全地取消此警告

在这种情况下,是的。

于 2018-07-30T19:34:28.707 回答