我无法解释为什么这个简单的代码无法编译。
class Foo { <T extends Foo> T method() { return this; } }
错误是:Type mismatch: cannot convert from Foo to T。 为什么不?T定义为Foo或其子类。
Type mismatch: cannot convert from Foo to T
T
Foo
更新:我在Java教程中找到了关于泛型方法的简短建议。
通用方法允许使用类型参数来表示方法的一个或多个参数的类型和/或其返回类型之间的依赖性。如果没有这种依赖性,则不应使用通用方法。
我的解释是,通用方法仅适用于两种情况。
显然,所讨论的简单代码的参数和返回类型之间没有依赖关系,因为没有参数。因此,通用方法是不合适的。
UPDATE2:现在我知道了,我注意到开源项目中这种反模式的示例。
UPDATE3:我认为我发现了不涉及多个参数或返回类型的通用方法的要求。多重继承似乎是Java教程中上述规则的例外。
<T extends Foo & Bar> void method(T foobar) { // Call Foo method. // Call Bar method. }
值得注意的是,Collectors实用程序类包括toList()不带参数的通用方法。在这种情况下,通用类型仅对返回类型进行参数化,这可能比实际用作返回类型的通用类型更安全。
Collectors
toList()
我认为您误解了Java泛型的工作原理:
<T extends Foo> T method() {
这意味着该方法的 调用者 可以选择Foo他们想要的任何子类型并提出要求。例如,你可以写
Foo foo = new Foo(); SubFoo subfoo = foo.<SubFoo>method();
…并期望SubFoo返回,但是您的method实现无法返回SubFoo,而这将失败。(我不会讲Scala,但是我认为这意味着您的Scala实现实际上不是“等效的”。)
SubFoo
method
如果你希望你的方法能够返回的子类型Foo的 实现 选,而不是调用者,那么就写
Foo method() { return this; }