如果我有一个界面和一个实现:
interface BaseInterface{ }
class Base implements BaseInterface{ }
在其他地方,我有一个方法:
<T extends Base> T foo() { /* return object of class T */ }
必须使用Base显式调用 foo()
才能分配给接口。 这很好用:
BaseInterface a = <Base>foo();
很好......但是如何明确调用以下方法?
<V extends Base> Map<String, V> bar() { /* return object of Map<String, V> */ }
这些似乎都不起作用:
Map<String, ? extends BaseInterface> m = <Base>bar();
Map<String, ? extends BaseInterface> m = <String, Base>bar();
Map<String, ? extends BaseInterface> m = <Map<String, Base>>bar();
答案 0 :(得分:2)
我认为你对如何使用泛型有点误解。
你现在拥有的是:
<T extends Base> T foo() {...}
,用英语表示foo
将返回一个Base
子类的对象(请记住,子类的意思是“此类或任何子类”)。但foo
不接受任何论证,因此foo
的实现不可能知道T
绑定的内容,也不可能重要 { {1}}必须:所有T
关心,而且所有调用者都关心,是它返回某种foo
。
基本上,你所拥有的就是这个:
Base
在这种情况下,您不需要使用泛型,因为Base foo() {...}
不需要担心类型信息:它只返回foo
的子类。如果你这样做会有所不同:
Base
因为<T extends Base> T doSomething(T input)
需要通用类型信息来决定返回类型。
不是将doSomething
和foo
声明为泛型,为什么不将它们声明为
bar
或者,甚至更好,
Base foo();
Map<String, Base> bar();
您现在可以编写客户端代码:
BaseInterface foo();
Map<String, BaseInterface> bar();
我知道这并没有直接回答你的问题,但我认为在你的情况下(给出示例代码)你真的不需要使用泛型来解决你的问题。将泛型与多态性混淆是很容易的。在这种情况下,多态性是你的朋友。
答案 1 :(得分:0)
Map<String, Base> m = bar<Base>();
根据您发布的代码,方法栏的V泛型参数应为Base或Base派生类。 BaseInterface不是从Base派生的。它是实现BaseInterface的Base。