我使用此代码收到编译器错误:
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);
答案 0 :(得分:5)
泛型继承与我们对OO继承的常规理解不同。请阅读此tutorial。
要编译代码,您可能需要更改方法语法,如下所示:
void set(Map<String, ?> foo) { }
编辑:正如dasblinkenlight评论的那样,如果您有任何计划在set方法中对Map进行修改,除非您定义了具体的类型,否则它将无法工作。
答案 1 :(得分:1)
虽然String[]
实际上是Object
,但这与Map<String,String[]>
实际上是Map<String,Object>
并不相同:协方差仿制药不存在。
更改声明
void set(Map<String,Object> foo) { }
使用通配符
void set(Map<String,?> foo) { }
将使您的代码编译,并尝试从foo
地图获取内容将起作用:
Object blah = foo.get("key");
但是,尝试向地图添加内容会失败:
<击> Object blah = foo.put(“key”); 击>
由于将地图放在地图中似乎是您的方法的目标(毕竟,必须有一个原因,您称之为set
),如果没有指定确切的话,您将无法使其工作类型。
答案 2 :(得分:0)
在泛型中使用类型参数时,继承不会以相同的方式工作。
这是一个过于简化的一般经验法则:
在声明和初始化通用对象时,<>
内的内容必须完全匹配。
答案 3 :(得分:0)
也许,Eclipse确实编译了你的代码,因为它是编译器错误。
您需要将set
的签名更改为set(Map<String, ?>)
才能进行编译。
它在第二种情况下用警告编译,不是吗?这是因为你使用原始地图(没有泛型)来绕过类型安全检查。