繁体   English   中英

泛型的Java编译器错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM