msharma
msharma

Reputation: 575

Generics confusion

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?

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.

Upvotes: 1

Views: 529

Answers (2)

erickson
erickson

Reputation: 269857

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).

Upvotes: 2

Michael Myers
Michael Myers

Reputation: 192035

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.

Upvotes: 1

Related Questions