拥有以下代码:
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)。
非常感谢
答案 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)