类型安全警告

时间:2012-03-23 10:23:54

标签: java generics collections covariance bounded-wildcard

在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);

提前致谢。

3 个答案:

答案 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会出现编译错误。