为什么一个使用通配符 “extends Object” 的 MAP 不能持有任何类型?

huangapple go评论79阅读模式
英文:

Why a MAP use generic wildcard extends Object cannot hold any type?

问题

抱歉,如果问题标题让您感到困惑。这是我的意思。

我有一个 Map<String, ? extends Object> studentDetails = new HashMap<>();,我希望它可以保存任意随机类型。

当我添加时

studentDetails.put("name", "John"); 
studentDetails.put("friendNames", Arrays.aslist("Kenny", "Peter", "friend3"));
studentDetails.put("courses", new HashSet<String>());
studentDetails.put("age", 18);

编译器报错

> 需要的类型:? extends Object 的捕获,提供的类型:
> String

> 需要的类型:? extends Object 的捕获,提供的类型:
> ArrayList

> 需要的类型:? extends Object 的捕获,提供的类型:
> HashSet

> 需要的类型:? extends Object 的捕获,提供的类型:
> Integer

为什么会出错呢?? extends Object 不应该可以捕获任何类型吗?如果我将其更改为 Map<String, Object>,那么就可以工作。

任何帮助将不胜感激!谢谢!

英文:

Sorry if the question title is confusing. Here is what I mean.

I have a Map&lt;String, ? extends Object&gt; studentDetails = new HashMap&lt;&gt;(); and I want it to hold any random types.

When I put

studentDetails.put(&quot;name&quot;, &quot;John&quot;); 
studentDetails.put(&quot;friendNames&quot;, Arrays.aslist(&quot;Kenny&quot;,&quot;Peter&quot;,&quot;friend3&quot;));
studentDetails.put(&quot;courses&quot;, new HashSet&lt;String&gt;());
studentDetails.put(&quot;age&quot;,18);

Compiler gives me :

> required type: capture of ? extends Object, Provided:
> String

> required type: capture of ? extends Object, Provided:
> ArrayList

> required type: capture of ? extends Object, Provided:
> HashSet

> required type: capture of ? extends Object, Provided:
> Integer

Why is it wrong? Shouldn't ? extends Object captures any type? If I change it to Map<String, Object>, then it works.

Any help would be appreciated! Thanks!

答案1

得分: 2

由于相同的原因,您无法执行以下操作:

List<Integer> ints = new ArrayList<>();

List<? extends Object> objs;

List<Integer>List<? extends Object> 的子类型,因此您可以将 List<Integer> 的实例分配给类型为 List<? extends Object> 的变量。但是,您不能执行以下操作,因为这会将一个字符串添加到整数列表中。编译器会捕获到这个错误。

objs = ints; // 可以
objs.add("abc"); // 不能将字符串添加到整数列表中

对于映射也是如此。

Map<String, ? extends Object> map;
Map<String, Integer> intMap = new HashMap<>();

map = intMap; // 可以
map.put("abc", "abc");  // 错误

编译器不知道您的映射引用的是什么类型,因此无法向其添加对象。

英文:

For the same reason you can't do this:

List&lt;Integer&gt; ints = new ArrayList&lt;&gt;();
		
List&lt;? extends Object&gt; objs;

List&lt;Integer&gt; is a subtype of List&lt;? extends Object&gt; so you can assign an instance of List&lt;Integer&gt; to a type List&lt;? extends Object&gt;. But you can't do the following because you would be adding a String into a list of Integers. And the compiler catches it.

objs = ints; // okay
objs.add(&quot;abc&quot;); // can&#39;t add String to list of ints

The same is true for maps.

Map&lt;String, ? extends Object&gt; map;
Map&lt;String, Integer&gt; intMap = new HashMap&lt;&gt;();

map = intMap; // okay
map.put(&quot;abc&quot;, &quot;abc&quot;);  //oops

The compiler has no idea what your map refers to so you can't add an object to it.

huangapple
  • 本文由 发表于 2020年7月27日 05:44:50
  • 转载请务必保留本文链接:https://go.coder-hub.com/63106039.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定