0

我在 countList 方法上遇到编译时错误。

public static void countList( List<? extends Number> list, int count ){
        for( int i = 0; i < count; i++ ){
            list.set(i, i-1);
        }
}

public static void clearList( List<?extends Number> list){
    list.clear();
}

它说: List 类型中的方法 set(int, capture#2-of ? extends Number) 不适用于参数 (int, int)

这个错误信息是什么意思?为什么我不能设置列表中的元素?为什么可以清除列表?

4

2 回答 2

3

因为它是“扩展数字的东西,但我不知道是什么”的列表。你不能只把整数放在那里,如果它实际上是一个双精度列表呢?

List<Double> list = new ArrayList<Double>();
list.add(Double.valueOf(4.5);
countList(list, 1);
Double d = list.get(0); //what happens here?  You put an Integer in there!  class cast exception

您可以清除该列表,因为对于该操作,Number 的哪个子类型实际上在其中并不重要。清楚就是清楚就是清楚。

于 2012-06-20T02:34:56.403 回答
2

问题是由于类型擦除,编译器不知道在运行时将哪种类型的 Number 添加到列表中。考虑这个例子:

public static void main(String[] args) {
        List<Integer> intList= new ArrayList<Integer>();
        // add some Integers to the list here
        countList(intList, 4);

}

public static void countList( List<? extends Number> list, int count ) {
        for( double d = 0.0; d < count; d++ ){
            list.set((int)d, d-1); // problem at d-1, because at runtime, 
            // the double result of d-1 will be autoboxed to a Double, 
            // and now you have added a Double to an Integer List (yikes!);
        }
}

因此,您永远无法使用该语法添加到通用类型的集合中。? extends SomeObject如果必须添加,可以将方法声明更改为:

  1. 将方法声明更改为public static void countList( List<Number> list, int count )
  2. 将方法更改为public static void countList( List<? super Integer> list, int count ).

无论哪种方式,编译器都会停止抱怨,因为它可以放心,您永远不会在 List 中添加与声明的 List 不同类型的任何内容。

于 2012-06-20T02:55:13.810 回答