有人可以解释为什么这是一个未经检查的演员
static void foo(Collection<? extends Number> collection) {
List<? extends Number> list = (List<? extends Number>) collection;
}
但这不是<?p?
static void bar(List<? extends Number> list) {
Collection<? extends Number> collection = (Collection<? extends Number>) list;
}
我认为它与捕获有关,但我想要一个明确的解释。
修改
我意识到这是一个措辞严厉的问题,正确的答案是&#34;因为List
扩展了Collection
&#34;。然而,在IntelliJ中,它会产生一个警告,当你投射到更具体的类型时,你通常不会得到警告。从下面的评论看来,这可能只是IntelliJ中的一个错误。确切的警告在下面的评论中(由于某种原因,我不能在这里重现它)。我没有收到以下任何一个警告
static void foo(Collection<Number> collection) {
List<Number> list = (List<Number>) collection;
}
static <T> void foo(Collection<T> collection) {
List<T> list = (List<T>) collection;
}
static void foo(Collection<?> collection) {
List<?> list = (List<?>) collection;
}
答案 0 :(得分:0)
因为从List<? extends Number>
到List<? extends Number>
的转换是向下转换,并且通常需要在运行时检查对象的类型。但是,如果类型参数实际上是扩展Number
的类,则运行时环境无法检查。该信息在运行时不可用,Java Generics(&#34;类型参数&#34;)仅存在于静态Java类型系统中,它们不会影响编译的代码。因此,如果Collection
是List
,则可以在运行时检查强制转换的唯一内容。
另一种情况是简单的向上转换,其中不需要运行时信息。您可以在编译时检查此强制转换是否始终有效。因此,缺乏关于运行时类型参数的信息是无关紧要的。