[英]Java compiler error with generics
我收到此代码的编译器错误:
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 []实际上是一个对象,并且与set()中的参数完全兼容。
从我的JDK 1.6升级到1.7之前,该错误没有显示在我的代码中。 我没有在Eclipse中看到将其关闭的开关。 如何获取此代码进行编译?
编辑:
如果使用中间变量,它会编译,并删除泛型:
Map anotherMap = myMap;
set(anotherMap);
泛型继承不同于我们对OO继承的常规理解。 请阅读本教程 。
为了使您的代码编译,您可能需要更改方法语法,如下所示:
void set(Map<String, ?> foo) { }
编辑:正如dasblinkenlight所评论的,如果您有任何计划对set方法中的Map进行修改,则除非您定义了具体的类型,否则它将无法工作。
尽管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");
但是,尝试将内容添加到地图将失败:
对象等等= foo.put(“ key”);
由于将事物放入地图中似乎是您方法的目标(毕竟,一定有理由将其称为set
),因此,如果不指定确切的类型,就无法使其工作。
在泛型中使用类型参数时,继承的工作方式不同。
这是一个过于简化的一般经验法则:
在声明和初始化通用对象时, <>
的内容必须完全匹配。
也许是因为它的编译器错误,Eclipse确实编译了您的代码。
您需要将set
签名更改为set(Map<String, ?>)
以进行编译。
它在带有警告的第二种情况下编译,不是吗? 这是因为您使用原始Map(不带泛型)来规避类型安全性检查。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.