Java 未经检查强制转换为类型参数警告,尽管是的实例
Java unchecked cast to type parameter warning despite being instance of
假设您有这个列表:
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 实例的对象在演员表之前被过滤掉了。这意味着,据我所知,转换永远不会失败
how exactly this is an unchecked cast
您唯一的保证是 e
是 AbstractXmlElement
的实例。但它可以是任何子类。因此,如果你有一个子类 A
和 B
都扩展了 AbstractXmlElement
,理论上类型约束意味着你可以尝试将 A
转换为 B
,这会失败,如果您将 B.class
作为参数传递并且您的集合包含 A
的实例。因此警告。
请注意,编译器不会去检查您的过滤器表达式来确定只有 E
的实例才能通过过滤器;特别是它不会去阅读文档,然后还假设文档是正确的。据它所知,c::isInstance()
只是另一种采用 Object
并返回 boolean
的随机方法。那时没有任何迹象表明只有 E
的实例保留在流中通过过滤器。
if it is safe to suppress this warning
在这种情况下,是的。
这是一个未经检查的转换,因为 E
的类型是 unknown at runtime。由于您正在检查 isInstance()
,因此您的代码是安全的。但是如果你想避免警告,你可以使用 c
来做演员:
.map(c::cast)
假设您有这个列表:
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 实例的对象在演员表之前被过滤掉了。这意味着,据我所知,转换永远不会失败
how exactly this is an unchecked cast
您唯一的保证是 e
是 AbstractXmlElement
的实例。但它可以是任何子类。因此,如果你有一个子类 A
和 B
都扩展了 AbstractXmlElement
,理论上类型约束意味着你可以尝试将 A
转换为 B
,这会失败,如果您将 B.class
作为参数传递并且您的集合包含 A
的实例。因此警告。
请注意,编译器不会去检查您的过滤器表达式来确定只有 E
的实例才能通过过滤器;特别是它不会去阅读文档,然后还假设文档是正确的。据它所知,c::isInstance()
只是另一种采用 Object
并返回 boolean
的随机方法。那时没有任何迹象表明只有 E
的实例保留在流中通过过滤器。
if it is safe to suppress this warning
在这种情况下,是的。
这是一个未经检查的转换,因为 E
的类型是 unknown at runtime。由于您正在检查 isInstance()
,因此您的代码是安全的。但是如果你想避免警告,你可以使用 c
来做演员:
.map(c::cast)