如果我有一个接口(interface)和一个实现:
interface BaseInterface{ }
class Base implements BaseInterface{ }
在其他地方我有一个方法:
<T extends Base> T foo() { /* return object of class T */ }
foo()
必须使用 Base 显式调用才能分配给接口(interface)。 这很好用:
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();
最佳答案
我认为您对如何使用泛型有点误解。
你现在拥有的是:
<T extends Base> T foo() {...}
在英语中,这意味着 foo
将返回一个对象,该对象是 Base
的子类(请记住,子类的意思是“此类或任何子类”)。但是 foo
不接受任何参数,所以 foo
的实现不可能知道 T
绑定(bind)到什么,< em>问题 T
绑定(bind)到什么:所有 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();
您现在可以编写您的客户端代码:
BaseInterface a = foo();
Map<String, BaseInterface> m = bar();
我知道这并不能直接回答您的问题,但我认为在您的情况下(给出示例代码)您并不真的需要使用泛型来解决您的问题。很容易将泛型与多态性混淆。在这种情况下,多态性是你的 friend 。
关于java - 显式调用泛型方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7218192/