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