I wrote this simple test code, by adapting a piece from a book, to help me understand the working of generic methods in Java. The line that I marked is supposed to work, why isn’t it?
import java.util.*; class Test { public static void main(String args[]){ List<Number> input = null; List<Number> output=null; output = Test.process(input); // fail, why?? } public static <E extends Number> List <? super E> process (List <E> nums){ List <E>eList = new ArrayList<E>(); return eList; } }
edit: Well, the code works when changing List<? super E> to List<E>, that’s great, but I’m still not sure if I may have missed something or if the book I took this from may have a mistake. Please read the question as it appears there:
- Given a method declared as:
public static < E extends Number > List < ? super E > process (List nums)
A programmer wants to use this method like this:
// INSERT DECLARATIONS HERE output = process(input);
Which pairs of declarations could be placed at // INSERT DECLARATIONS HERE to allow the code to compile? (Choose all that apply.)
A. ArrayList<Integer> input = null; ArrayList<Integer> output = null; B. ArrayList<Integer> input = null; List<Integer> output = null; C. ArrayList<Integer> input = null; List<Number> output = null; D. List<Number> input = null; ArrayList<Integer> output = null; E. List<Number> input = null; List<Number> output = null; F. List<Integer> input = null; List<Integer> output = null; G. None of the above.
Answer: B, E, and F are correct. The return type of process is definitely declared as a List, not an ArrayList, so A and D are wrong. C is wrong because the return type evaluates to List<Integer>, and that can’t be assigned to a variable of type List<Number>. Of course all these would probably cause a NullPointerException since the variables are still null—but the question only asked us to get the code to compile.
None of the options mentioned on the book have worked on my code. Can I safely mark it as a mistake on Kathy Sierra’s part or am I missing something here?
The problem is that you are declaring the return type of your method as
but assigning it to a
So you should either assign it to a
or declare the return type as
(Verbose formatting because inline code does not show generics correctly.)
If the book claims assigning the return value of the method is possible in the way you describe it then indeed it seems to be a mistake in the book. It would be correct if the method returned a List of E (as above).