Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/348.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 显式调用泛型方法_Java_Generics - Fatal编程技术网

Java 显式调用泛型方法

Java 显式调用泛型方法,java,generics,Java,Generics,如果我有接口和实现: interface BaseInterface{ } class Base implements BaseInterface{ } 在其他地方我有一个方法: <T extends Base> T foo() { /* return object of class T */ } 好的。。。但是我如何显式调用下面的方法呢 <V extends Base> Map<String, V> bar() { /* return object of

如果我有接口和实现:

interface BaseInterface{ }
class Base implements BaseInterface{ }
在其他地方我有一个方法:

<T extends Base> T foo() { /* return object of class T */ }
好的。。。但是我如何显式调用下面的方法呢

<V extends Base> Map<String, V> bar() { /* return object of Map<String, V> */ }
Map bar(){/*返回Map*/}
这些似乎都不起作用:

Map<String, ? extends BaseInterface> m = <Base>bar();
Map<String, ? extends BaseInterface> m = <String, Base>bar();
Map<String, ? extends BaseInterface> m = <Map<String, Base>>bar();
Map m=bar();
Map m=bar();
Map m=bar();
Map m=bar();

根据您发布的代码,方法栏的泛型参数应该是Base或基类派生类。BaseInterface不是从Base派生的。它是实现BaseInterface的基础。

我认为您对如何使用泛型有点误解

您现在拥有的是:

<T extends Base> T foo() {...}
在这种情况下不需要使用泛型,因为
foo
不需要担心类型信息:它只返回
Base
的子类。如果您这样做,情况会有所不同:

<T extends Base> T doSomething(T input)
或者,甚至更好

BaseInterface foo();
Map<String, BaseInterface> bar();
BaseInterface foo();
地图条();
您现在可以编写客户端代码:

BaseInterface a = foo();
Map<String, BaseInterface> m = bar();
BaseInterface a=foo();
Map m=bar();

我知道这不能直接回答您的问题,但我认为在您的情况下(给出示例代码),您不需要使用泛型来解决您的问题。很容易混淆泛型和多态性。在本例中,多态性是您的朋友。

使用语法
SomeClass name=new SomeClass()怎么办:
Map m=bar()?在您的示例中,BaseInterface不是导致错误的Base的子类型。@Kru:没错,因此您必须显式调用该方法,告诉它您想要一个映射,即使您正在将其分配给Map。这就是问题所在。@Mark:您不能将
Map
类型的变量分配给
Map
类型的变量。例如,您不能执行
Map m=new HashMap()
,原因与您不能执行
List l=new ArrayList()
相同。如果可以这样做,就有可能在映射中插入一个不是
Base
BaseInterface
对象,违反泛型约束。@CameronSkinner:我不相信这是真的。在上面的示例中,
BaseInterface a=foo()是有效的。你只需要从泛型中明确你想要的实现。我的映射是
map
。。。我无法将其切换到
Map
。那么您最终应该更改bar签名:Map bar(){}。我想您还没有完全理解泛型是如何工作的。无论如何,V扩展了Base,而BaseInterface不扩展Base。所以无论你想做什么,这都是错误的。我知道泛型是如何工作的。Base实现了BaseInterface,因此将Base分配给BaseInterface的对象是完全可以接受的。是的,但要做到这一点,您不需要泛型。请仔细阅读@Cameron Skinner的答案。他解释得很好。我把问题简化了,缩短了篇幅。我意识到这可能会引起混乱。真正的问题是如何显式调用方法
Map bar()。只要声明
bar
返回
Map
,你就会得到你想要的。@Cameron Skinner:我不同意你的答案。查看
Collections.emptyList()
.emptyMap()
等方法的声明。声明是
静态映射emptyMap()
。根据您的推理,他们为什么不直接执行静态映射emptyMap()
?因为这样你就不能把它分配给
地图
或类似的东西。使用它的声明方式,您现在可以执行
Map foo=Collections.emptyMap()
<T extends Base> T doSomething(T input)
Base foo();
Map<String, Base> bar();
BaseInterface foo();
Map<String, BaseInterface> bar();
BaseInterface a = foo();
Map<String, BaseInterface> m = bar();