1

具有以下代码:

    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)

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

非常感谢

4

3 回答 3

2

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

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

在这里,您试图将 aInteger放在 a 上Stack<Double>,这显然是不正确的。

基本上当你像这样使用通配符时,你可以取出值但你不能把值放进去因为编译器不能保证这样做是有效的。

于 2011-06-25T07:59:44.543 回答
2

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

这里的具体问题是您可以执行以下操作:

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

在底层结构中意味着 integer.push(r); // 类型不匹配

(Scala 中的编程在第 19 章中对客户端与提供者端(共同/相反)差异有清晰的解释。即使您不熟悉 Scala,也推荐阅读)

于 2011-06-25T08:02:45.113 回答
1

非常明确的答案在这里 如何添加到 List<? 扩展 Number> 数据结构?

于 2011-06-25T07:58:50.123 回答