2016-11-09 90 views
1
<T extends Number> void m1(List<T> list) { 
    list.add(list.get(0)); 
} 

void m2(List<? extends Number> list) { 
    list.add(list.get(0)); 
} 

我发现很难理解上述两种方法之间的区别。
第一种方法m1()编译成功,但方法m2()产生一个编译器错误:Java通配符捕获

The method add(capture#1-of ? extends Number) in the type List<capture#1-of ? extends Number> is not applicable for the arguments (capture#2-of ? extends Number)

+1

类型擦除.... –

回答

2

因为你不能类型与上界的列表上添加ITEN!你可以有一个列表或列表,其中一个不适合其他修改操作!

List<? extends Number> list = new ArrayList<Integer>(); 
List<? extends Number> list = new ArrayList<Double>(); 
List<? extends Number> list = new ArrayList<Long>(); 

在这种情况下,变量列表可以有扩展Number的任何类型。所以你可以在你的方法中传递它,例如。但在那里,你现在真的不知道类型可能。你可以有一个ArrayList,并说它添加一个新的Double。在编译时有意义,因为Double扩展Number,但在运行时,列表不能是这种类型并抛出Exception。

只要记住,当你使用上限,<? extends T>,你cant修改列表,只是读它!还有就是Oracle tutorial(见通配符章节内容 - 上界通配符下界通配符等)