Having the below code:
Stack<Integer> integers = new Stack<Integer>();
Stack<? extends Number> numbers = integers;
Number n = numbers.pop();
numbers.push(3);
numbers.push(n);
I get compilation errors on the last two lines, but although I've given it some thought I don't understand why the compilation errors are there.
The method开发者_如何学Python push(capture#2-of ? extends Number) in the type Stack<capture#2-of ? extends Number> is not applicable for the arguments (int)
When I comment the last line, I still get the above compilation error, but from my understanding the compiler should be able to infer the correct type (Stack) from those lines.
Thanks a lot
The last two lines aren't valid because numbers
could be a stack of any numeric type. Consider this similar code:
Stack<Double> doubles = new Stack<Double>();
Stack<? extends Number> numbers = doubles;
Number n = numbers.pop();
numbers.push(3);
numbers.push(n);
Here you're trying to put an Integer
onto a Stack<Double>
which obviously isn't correct.
Basically when you use wildcarding like this, you can get values out, but you can't put values in because the compiler can't guarantee it's valid to do so.
Generics covariance in Java is handled at the client. i.e. You don't have the semantics to say that a Stack is covariant and let the compiler check that the operations you are allowing (like push) is valid in a covariance model. (push is not).
The specific issue here is that you can do something like this:
Number r = new Rational(a,b); // rationals are also numbers
number.push(r);
which in the underlying structure implies integer.push(r); // type mismatch
(Programming in Scala has a crystal clear explanation of client vs provider side (co-/contra-)variance on Chapter 19. A recommended read even if you are not into Scala)
very clear answer here How can I add to List<? extends Number> data structures?
精彩评论