2012-03-23 81 views
0

在Maurice Naftalin,Philip Wadler撰写的“Java泛型和收集”一书中,我遇到了泛型限制,并提出了疑问。可能是书中的答案,但我认为我很困惑。
在下面的代码:
类型安全警告

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

报告的警告和错误是什么? – WhiteKnight 2012-03-23 10:30:36

回答

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>和你想添加一个 数字在里面。所以为了避免这种错误(并且因为验证是在编译时完成的),如果您不确定它是否可行,则不能添加内容。


关于你的警告,我没有任何。

0

1) 这行不应该给出警告(当我尝试它时不会发出警告)。你看到了哪个警告?

2) 由于lists.get(0)的类型是List<?>而不是List<Integer,因此存在编译时错误。这意味着,编译器不知道列表是否允许包含整数...

0

2)为什么会出现一个编译时错误在第四行:

lists.get(0)。添加(5);

因为您定义了List> lists = new ArrayList>(); 并且您试图在列表中添加简单整数5。这就是为什么,IDE给编译错误。