明确地调用泛型方法

时间:2011-08-28 00:11:57

标签: java generics

如果我有一个界面和一个实现:

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();

2 个答案:

答案 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) 需要通用类型信息来决定返回类型。

不是将doSomethingfoo声明为泛型,为什么不将它们声明为

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。