繁体   English   中英

通配符,Java中的通用

[英]wildcard, generic in java

我在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?扩展Number)不适用于参数(int,int)

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

因为它是“扩展数字的东西,但我不知道是什么”的列表。 您不能只将整数放在其中,如果实际上是一个双精度列表怎么办?

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的哪个子类型都没有关系。 清除是清除。

问题在于,由于类型擦除,编译器在运行时不知道将哪种类型的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 添加到通用类型的Collection中? extends SomeObject ? extends SomeObject语法。 如果必须添加,则可以将方法声明更改为:

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM