在Maurice Naftalin,Philip Wadler撰写的Java Generics and Collections一书中,我经历了泛型限制,并提出疑问。可能是书中已经回答了,但我觉得我很困惑。
在以下代码中:
List<List<?>> lists = new ArrayList<List<?>>();
lists.add(Arrays.asList(1,2,3));
lists.add(Arrays.asList("four","five"));
assert lists.toString().equals("[[1, 2, 3], [four, five]]");
正如书中所说,嵌套通配符实例化没有问题,因为对于第一个列表,它知道它将包含列表类型的对象。
但我尝试修改上面的代码并提出了一个警告和一个编译时错误。我试着这样做:
List<?> sample= Arrays.asList(1,2,3,4.14);
List<List<?>> lists = new ArrayList<List<?>>();
lists.add(Arrays.asList(1,2,3));
lists.get(0).add(5);
lists.add(Arrays.asList("four","five"));
System.out.println(sample.toString());
assert lists.toString().equals("[[1, 2, 3], [four, five]]");
我的问题是: 1)如果我写的话,在第一行:
List<?> sample= Arrays.asList(1,2,3);
此处未发出警告,但如上所述,如果我写的话:
List<?> sample= Arrays.asList(1,2,3,4.14);
发出警告。为什么呢?
2)为什么第四行有编译时错误:
lists.get(0).add(5);
提前致谢。
答案 0 :(得分:3)
存在编译时异常,因为lists.get(0)
返回List<?>
你不知道这个列表的类型是什么,你知道你可以从中获取元素(它至少是Object
),但是你不能把它放进去(因为你'不确定它是否合适。
如果你写的话会附加什么:
List<List<?>> lists = new ArrayList<List<?>>();
lists.add(new ArrayList<String>());
lists.get(0).add(5);
lists.add(Arrays.asList("four","five"));
您有一个ArrayList<String>
并且您正在尝试在其中添加一个数字。因此,为了避免这种错误(并且因为验证是在编译时完成的),如果您不确定它是否可行,则无法添加内容。
关于你的警告,我没有。
答案 1 :(得分:0)
1) 这一行不应该发出警告(当我尝试时它不会发出警告)。您看到了哪个警告?
2)
存在编译时错误,因为lists.get(0)
的类型为List<?>
,而不是List<Integer
。这意味着编译器不知道列表是否允许包含整数...
答案 2 :(得分:0)
2)为什么第四行有编译时错误:
lists.get(0)。新增(5);
因为你定义了List&gt; lists = new ArrayList&gt;(); 并且您正尝试在List中添加简单整数5。这就是为什么IDE会出现编译错误。