【问题标题】:wildcard, generic in java通配符,java 中的泛型
【发布时间】:2012-06-20 02:30:45
【问题描述】:

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)

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

【问题讨论】:

标签: java generics


【解决方案1】:

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

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 子类型并不重要。清楚就是清楚。

【讨论】:

    【解决方案2】:

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

    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&lt;Number&gt; list, int count )
    2. 将方法改为public static void countList( List&lt;? super Integer&gt; list, int count )

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-12
      • 1970-01-01
      • 2017-02-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多