Java泛型方法: inconsistency when inferring upper bound on return type from argument type

标签 java generics type-inference type-erasure

考虑以下因素:

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 作为返回类型参数的上限,但在“不安全”情况下却不能?

我想我明白为什么它在“不安全”情况下不起作用,因为 T 被对象删除,但也许有点惊讶它在“安全”情况下起作用。至少我觉得它不一致。

最佳答案

Col<Baz> col = Test.unsafe (new Foo ());
在这种情况下,

Test.unsafeT 推断为 Object;由于所有内容都扩展了 Object,因此满足边界。

Col<Baz> col = Test.safe (new Tag<Foo> ());
在这种情况下,

T 不能被推断为 Object:它是 Foo,因为您已经说过它是 Foo,没有任何界限。同样,V 正是 Baz。由于 Baz 没有扩展 Foo,因此这是一个编译器错误。

关于Java泛型方法: inconsistency when inferring upper bound on return type from argument type,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49452617/

相关文章:

Java 8 Lambda 同时分组 X 和 Y

Java:泛型、指向 <? 的父类(super class)类型引用扩展父类(super class)>类型引用

C# 通用接口(interface)白名单候选过滤

generics - 如何以类型安全的方式从通用列表中检索项目

java - 在 Actionlistener 中使用 EventObject.getSource

java - fragment 回栈

Java:返回一个实现具有类型推断的接口(interface)的类

c++ - "auto;"类型推断

f# - 如何使用重载的静态运算符

java - 使用 Java 动态创建类