【发布时间】:2012-09-07 09:02:07
【问题描述】:
今天我遇到了以下问题。考虑设置:
interface A {
void foo();
}
interface B {
void bar();
}
class Impl implements A,B {
public void foo() { }
public void bar() { }
}
class Usage {
void worksAsParameter(){
acceptIt(new Impl());
}
<T extends A & B> void acceptIt(T foo){
}
<T extends A & B> T returnIt(){
return new Impl(); // <-- Compile error
}
}
除了标记的最后一条语句外,代码编译。 Eclipse 给了我error: Type mismatch: cannot convert from Impl to T
我的问题是:为什么Impl 可以分配给T 作为参数(显示在worksAsParameter 但不是当T 是返回类型时?
另外,在Impl 不满足的情况下,除了null,还有什么表达式可以满足T 类型?
请注意,这个问题与this SO question 不同,虽然相似。
编辑:修正错字。
=== 总结 ===
看来我误解了通用返回类型的工作原理。我会尝试写下我对它的新理解。
让我们看看这个问题:
<T extends A & B> T returnIt(){
return new Impl(); // <-- Compile error
}
我最初的假设是实现类(在本例中为 Usage)决定了 T 的具体类型,但限制是它必须扩展 A 和 B。显然是调用者/调用站点来决定T 是什么,Usage 必须提供一个可分配给T 的值。然而,由于T 是一个编译时交易,所以除了null 之外不可能提供这样的值(因为它可以分配给任何东西)。
Afaik 这意味着表单的任何代码都只能返回null:
<T extends A> T returnIt(){
return x; // <-- Compile error
}
一个相当不直观的功能,希望在不同的环境中更有用。谢谢彼得!
【问题讨论】:
标签: java generics inheritance interface return-value