要理解这一点,我们需要理解以下实际含义:
static <F extends Foo> F getFoo(String string) {
return null;
}
getFoo
返回某种类型的值,该值必须从调用所在的上下文中推断。此外,它还设置了一个约束,即推断的类型必须是
Foo
.
因为
null
为了说明这一点,请尝试以下变体:
import java.util.List;
public class StaticMethodWithBoundedReturnType {
static class Foo {
}
static class Bar extends Foo {
}
static <F extends Foo> F getFoo(String string) {
return new Bar();
}
public static void main(String[] args) {
// Compiles without error, even though List does not extend Foo.
List<Integer> list = getFoo("baz");
}
}
这会产生编译错误
StaticMethodWithBoundedReturnType.java:11: error: incompatible types:
Bar cannot be converted to F
return new Bar();
^
为什么Bar和F不兼容?
回答:因为
F
( R & ? extends Foo )
哪里
R
结果的类型
格福
分配给。而且,在
格福
R
将。(事实上,它可以有很多不同的类型!)
<F extends Foo> F getFoo(String string)
有问题。但是,请考虑:
static <F extends Foo> F getFoo(Class<F> clazz) {
return class.newInstance();
}
这是合法的,并将返回一个满足运行时类型安全(本地)的值。但你会的
然后
如果尝试将其分配给
List<Integer>
:
StaticMethodWithBoundedReturnType.java:16: error: incompatible types:
inference variable F has incompatible bounds
List<Integer> list = getFoo(Bar.class);
^
equality constraints: Bar
upper bounds: List<Integer>,Foo
where F is a type-variable:
F extends Foo declared in method <F>getFoo(Class<F>)
1 error
List<Integer> list = getFoo("baz");
这是合法的因为
结果的类型是交集类型
(List<Integer> & ? extends Foo)
. 实际上,这种交集类型是可实现的;例如
class Baz extends Bar implements List<Integer> { /* list methods */ }
(事实上在这方面没有实施
Baz
在我们的课程中上课是无关紧要的。可能有一个。)
list
将被分配
无效的
,这不是运行时类型冲突。