First of all, of course all the three correct answers (!) are incorrect, here is why (It’s might look exhaustive but necessary):
Whenever we use wildcard in our codes, compiler uses a technique known as “Wildcard Capture”. It basically is a way for compiler to deal with wildcard means that internally compiler converts the wildcard types to some anonymous type like this:
List<?> becomes List<capture#000 of ?>
List<? extends Number> becomes List<capture#000 of ? extends java.lang.Number>
List<? super Number> becomes List<capture#000 of ? super java.lang.Number>
And so on...
So now what is the capture of a wildcard compatible to? Means what kind of type a the capture of a wildcard can assign to?
Well, the answer is another wildcard! But never, ever a concrete type! So do you get the point?
The return value of the method is: List <? super E> and you never can assign it to a concrete type like List<Integer> and this is the case in the whole 3 method call which all are wrong! To fix the method call
you should write:
<E extends Number> List<? super E> process(List<E> nums)
when you use the List<Integer> as the input the compiler infer the type E as Integer so the output should be compatible to <? super Integer> which is again <? super Integer>, so it should be:
ArrayList<Integer> inputA = null;
List<? super Integer> outputA = null;
outputA = DumpArray.process(inputA);
or in the second method call it should be:
List<Number> inputB = null;
List<? super Integer> outputB = null;
Or
List<? super Number> outputB = null;
outputB = process(inputB);
One last important point:
The wildcard capture is never compatible even to its bounds even if the bound is a final class!
Like this:
List<? extends
String> lst1 = null
List<String> lst = lst2; //Compile error!
And unbounded wildcard capture (<?>) is compatible to nothing except itself!
That’s it! I have a K&B of
SCJP 6 and could not find this question, Are you sure that they mentioned those as correct answer?!!