请考虑以下事项:
class Col<T> { }
class Tag<T> { }
class Foo { }
class Bar { }
class Baz extends Bar { }
class Test {
static <T, V extends T> Col<V> safe (Tag<T> t) { return null; }
static <T, V extends T> Col<V> unsafe (T t) { return null; }
}
然后这将产生所需的编译时错误(因为Baz不扩展Foo):
Col<Baz> col = Test.safe (new Tag<Foo> ());
但这不会:
Col<Baz> col = Test.unsafe (new Foo ());
以供参考,这是按预期编译的(因为Baz扩展了Bar):
Col<Baz> col = Test.safe (new Tag<Bar> ());
为什么编译器(Java 8)可以推断并使用T作为'safe'情况下返回类型参数的上限,但不是'不安全'的情况?
我想我理解为什么它在'不安全'的情况下不起作用,因为T被Object删除,但可能有点惊讶它适用于'安全'的情况。至少我发现它不一致。
答案 0 :(得分:4)
Col<Baz> col = Test.unsafe (new Foo ());
在这种情况下, Test.unsafe
推断T
为Object
;因为所有内容都延伸Object
,所以边界得到满足。
Col<Baz> col = Test.safe (new Tag<Foo> ());
在这种情况下, T
无法推断为Object
:它是Foo
,因为您已经说过它Foo
V
,没有任何界限。同样,Baz
正是Baz
。由于Foo
不会扩展calendar.month_name[3]
,因此编译错误。