Javagenerics放在Map <String,? 扩展List >
有没有办法以类型安全的方式进行以下实现?
public void myMethod( Map<String, ? extends List> map ) { map.put("foo", Collections.singletonList("bar"); }
上述实现不起作用。 它需要Map<String, ? super List>
Map<String, ? super List>
正确编译方法map.put()
。 但是myMethod不会以这种方式接受List的任何子类型。 所以,我必须使用Map<String, ? extends List>
Map<String, ? extends List>
。 如何以类型安全的方式解决此问题?
public void myMethod( Map> map ) { map.put("foo", Collections.singletonList("bar") ); }
您不能将List
( Collections.singletonList()
的返回类型放入? extends List
的Map
,因为实际类型可能是List
任何实现。例如,将通用List
放入Map
是不安全的。 Map
因为List
可能不是LinkedList
。但是,我们可以轻松地将LinkedList
放入
的Map
中。
我想你已经在考虑你的仿制药了。 你不必使用? extends
? extends
为非generics类。 例如, List
将保存任何Object
不需要? extends
来添加对象。 List
只接受>
List
对象而不是List
对象[通用类不基于它们的参数inheritance]。 这是哪里? extends
? extends
发挥作用。 要将List
和List
到List
,类型必须是List
>
List
。 >
Map
不会工作吗? 有什么特别的原因你必须在那里有一个通配符吗?
将Collections和Generics一起使用时,有一个非常简单的原则。 它被称为“获取和放置原则”:
当你只从集合中获取值时使用“扩展”通配符,当你只将PUT值放入集合时使用“超级”通配符,当你想要get和put时不使用任何通配符。
所以,正如你所看到的,根据这个原则,最初的例子是无效的。
想象一下,如果有人传给你一个Map
。 您输入的值是Collections.singletonList的结果,它不是 ArrayList
。
您不能在Map中接受List的任何子类型,然后期望能够添加您自己的,可能不兼容的子类型。