今天我遇到了以下问题。考虑设置:
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
null
T
Impl
请注意,尽管相似,但此问题与此 SO 问题不同。
编辑:修正错字。
=== 总结 ===
看来我误解了通用返回类型的工作原理。我将尝试写下我对它的新理解。
让我们看一下这个问题:
<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
}
一个相当不直观的功能,希望在不同的环境中更有用。谢谢彼得!