Tutorial :Generics confusion



Question:

Below is a question from Kathy & Bert Bates SCJP 5 preparation CD. I have posted this elsewhere too, but have not gotten a satisfactory explanation until now.... Please help me understand this:

public class BackLister {      //Insert code here    {      List<T> output=new LinkedList<T>();        for(T t:input)          output.add(0,t);       return output;      }    }  

Which of the following can be inserted at //Insert code here?

  • A. public static <T> List<T> backwards(List<T> input)
  • B. public static <T> List<T> backwards(List<? extends T> input)
  • C. public static <T> List<T> backwards(List<? super T> input)
  • D. public static <T> List<? extends T> backwards(List<T> input)
  • E. public static <T> List<? super T> backwards(List<T> input)
  • F. public static <? extends T> List<T> backwards(List<T> input)

I understand that A and B are correct; however, not why are D and E also right. I can see that C and F are also incorrect. Can someone please tell me why D and E are correct.


Solution:1

Answer D, public static <T> List <? extends T> backwards(List <T> input), returns a list that can contain type T or any of its subclasses. Since it can hold T, it can hold any element in the input, and is "correct" in that sense.

Answer E, public static <T> List <? super T> backwards(List <T> input), is similar, but returns a list that can hold T or any super class. Since it can also hold the input elements, it is also "correct."

Choosing one of these alternatives will impact what a user might expect to do with the resulting list.

  • With the List<? extends T> output, one can iterate over the list and assign each element to a variable of type T, but no elements, even of type T, can be safely added to the List. (Someone might be referring to this list as List<SubT>, and would get a ClassCastException when trying to retrieve the T as a SubT.)

  • With the List<? super T> output, one can safely add elements to the List if they are of type T. However, an element from the list can only be safely assigned to a variable of type Object. (Someone might be referring to this list as List<Object>, and adding instances of Object or other superclasses of T).

  • With the List<T>, one can safely assign the elements of the list to a variable of type T, and can add elements of type T to the list (assuming it's a modifiable List implementation).


Solution:2

Because a List<T> is a List<? extends T> and a List<? super T>, by definition.
? extends T is a wildcard indicating T or a subtype, and ? super T is a wildcard indicating T or a supertype. Therefore, returning a List<T> will satisfy both return types.

There are reasons for preferring to return one or the other, but the main point here is that they are legal.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »