我已经阅读了有关此主题的几篇文章。
这是一个特别好的帖子
我以为我理解了PECS的概念,并试图建立一个小例子来测试它。
import java.util.Map;
import java.util.HashMap;
class Test {
public static void main(String[] args) {
Map<String, ? super Number> map = new HashMap<>();
map.put("int", 1);
map.put("double", 1.0);
map.put("long", 100000000000L);
print(map);
}
public static void print(Map<String, ? extends Number> map) {
map.forEach((k, v) -> System.out.printf("Key: %s, Val: %s%n", k, v));
}
}
我知道我需要使用super
才能将多个子类型插入到同一地图中。
但是在印刷方面。我认为使用extends
就足够了,因为PECS(制片人扩展(
相反,我得到这个:
Error:(12, 15) java: incompatible types: java.util.Map<java.lang.String,capture#1 of ? super java.lang.Number> cannot be converted to java.util.Map<java.lang.String,? extends java.lang.Number>
在这两种情况下,Number
就足够了,而且是最充分的。
如前所述super
没有意义;你也可以写Object。
Map<String, Number> map = new HashMap<>();
有了这个,您可以将数字或数字的子项放入地图中。或者从地图中获取数字或数字的父级。
现在,如果您使用:
public static void print(Map<String, ? extends Number> map) {
您不能将Double
(或其他任何东西(放入该map
中,因为实际的 map 参数可能是Map<String, Integer>
。因此Map<String, Number>
.
由于 java 的类型系统不是很强/表现力很强,一个好的规则是为元级构造保留extends
(=当你需要它们时(。对于简单的数据结构,PECS 遵循数据流。
这是因为
Map<String, ? super Number> map
可能包含任何值,请尝试此操作
Map<String, Object> map1 = new HashMap<>();
map1.put("1", "2");
Map<String, ? super Number> map = map1;
没有编译错误