0

我收到此代码的编译器错误:

Map<String, String[]> myMap;

void set(Map<String, Object> foo) { }

set(myMap); // generates error

Error: "The method set(Map<String,Object>) in the type XXX is not applicable for the arguments (Map<String,String[]>)"

这对我来说毫无意义,因为 String[] 实际上是一个 Object,并且与 set() 中的参数完全兼容。

在我从 JDK 1.6 升级到 1.7 之前,这个错误没有出现在我的代码中。我在 Eclipse 中没有看到将其关闭的开关。如何让这段代码编译?

编辑:

如果我使用中间变量,它会编译,并删除泛型:

Map anotherMap = myMap;
set(anotherMap);
4

4 回答 4

5

泛型继承不同于我们对OO继承的常规理解。请阅读本教程

要编译您的代码,您可能需要更改方法语法,如下所示:

void set(Map<String, ?> foo) { }

编辑:正如 dasblinkenlight 评论的那样,如果您有任何计划在 set 方法中对 Map 进行修改,除非您定义了具体类型,否则它将不起作用。

于 2012-10-24T21:47:23.153 回答
1

虽然String[]实际上是 a Object,但这与说Map<String,String[]>实际上是 a不同Map<String,Object>:泛型的协方差不存在。

更改声明

void set(Map<String,Object> foo) { }

与通配符为一

void set(Map<String,?> foo) { }

将使您的代码编译,并尝试从foo地图中获取内容:

Object blah = foo.get("key");

但是,尝试向地图添加内容会失败:

对象 blah = foo.put("key");

由于将事物放入地图似乎是您的方法的目标(毕竟,您调用它一定是有原因的set)如果不指定确切的类型,您将无法使其工作。

于 2012-10-24T21:51:29.080 回答
0

在泛型中使用类型参数时,继承的工作方式不同。

这是一个过度简化的一般经验法则:

<>在声明和初始化泛型对象时,s 中的内容必须完全匹配。

于 2012-10-24T21:51:12.467 回答
0

也许,Eclipse 确实编译了您的代码,因为它的编译器错误。

您需要更改 to 的签名set才能set(Map<String, ?>)使其编译。

它在第二种情况下编译并带有警告,不是吗?这是因为您使用原始 Map(没有泛型)来规避类型安全检查。

于 2012-10-24T21:52:32.450 回答