java绑定通配符泛型的编译器错误

时间:2011-06-25 07:45:56

标签: java generics bounded-wildcard

拥有以下代码:

    Stack<Integer> integers = new Stack<Integer>();
    Stack<? extends Number> numbers = integers;
    Number n = numbers.pop();
    numbers.push(3);
    numbers.push(n);

我在最后两行得到了编译错误,但是虽然我已经考虑了一些,但我不明白为什么会出现编译错误。

The method push(capture#2-of ? extends Number) in the type Stack<capture#2-of ? extends Number> is not applicable for the arguments (int)

当我评论最后一行时,我仍然得到上面的编译错误,但根据我的理解,编译器应该能够从这些行推断出正确的类型(Stack)。

非常感谢

3 个答案:

答案 0 :(得分:2)

最后两行无效,因为numbers可能是任何数字类型的堆栈。考虑这个类似的代码:

Stack<Double> doubles = new Stack<Double>();
Stack<? extends Number> numbers = doubles;
Number n = numbers.pop();
numbers.push(3);
numbers.push(n);

在这里,您尝试将Integer放到显然不正确的Stack<Double>上。

基本上当你使用这样的通配符时,你可以获得值 out ,但你不能将值放在中,因为编译器不能保证它有效如此。

答案 1 :(得分:2)

Java中的泛型协方差在客户端处理。即,您没有语义来说Stack是协变的,并让编译器检查您允许的操作(如push)在协方差模型中是否有效。 (推不是)。

这里的具体问题是你可以这样做:

Number r = new Rational(a,b); // rationals are also numbers
number.push(r);

在底层结构中暗示integer.push(r); //类型不匹配

(Scala中的编程对第19章中的客户端与提供者端(共同/反向)差异有一个清晰的解释。即使您没有进入Scala,也建议阅读)

答案 2 :(得分:1)

相关问题