使用通配符和通配符的问题

mmo*_*sen 11 java generics arguments wildcard map

我有一个方法,返回map定义为:

public Map<String, ?> getData();
Run Code Online (Sandbox Code Playgroud)

这个方法的实际实现对我来说并不清楚,但是,当我尝试这样做时:

obj.getData().put("key","value")
Run Code Online (Sandbox Code Playgroud)

我得到以下编译时错误消息:

方法put(String,capture#9-of?)在Map类型中不适用于参数(String,String)

问题是什么?是String不是输入任何内容?

提前致谢.

Ben*_*ngs 15

返回类型

Map<String, ?>
Run Code Online (Sandbox Code Playgroud)

是相同的

Map<String, ? extends Object>
Run Code Online (Sandbox Code Playgroud)

返回的具体类型可能是a Map<String, AnyClass>.你不能把一个String成一个AnyClass,因此错误.

一个好的一般原则是不在方法返回类型中使用通配符.


Jon*_*eet 10

通配符意味着"值类型参数可以是任何东西" - 它并不意味着"你可以使用它,就好像它是你想要它的任何东西".换句话说,a Map<String, UUID>作为Map<String, ?>- 有效- 但您不希望能够将String值放入其中.

如果你想要一个绝对可以接受字符串值的地图,你想要:

Map<String, ? super String>
Run Code Online (Sandbox Code Playgroud)

  • String类是final,所以只需要Map <String,String> (5认同)

Har*_*ded 5

Map<String, ?>是一种缩写形式,Map<String,? extends Object>并不意味着任何东西都可以作为价值添加。它表示 Map 对象可以具有任何扩展的泛型值类型Object

这意味着 Map 对象也可以是 aHashMap<String, String>或 a HashMap<String, Integer>。因为编译器无法检查将接受哪些值类型,所以他不会让您以该值类型作为参数调用方法。

笔记:

  • 你可以用值类型作为返回值调用方法,因为一切都必须扩展对象(? extends Object)
  • AMap<String, ? super String>会产生相反的效果:您始终可以使用 String 作为参数,但返回类型不清楚。