Perplexity of generics

Below is a question from Katy and Bert Bates's SCJP 5 training CD. I've also posted this elsewhere but still haven't gotten a satisfactory explanation. 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 into //Insert code here

?

  • A .public static <T> List<T> backwards(List<T> input)

  • In .public static <T> List<T> backwards(List<? extends T> input)

  • The 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)

  • The F .public static <? extends T> List<T> backwards(List<T> input)

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

+1


a source to share


2 answers


Answer D,, public static <T> List <? extends T> backwards(List <T> input)

returns a list, which can contain the type T

or any of its subclasses. Since it can contain T

, it can hold any element in the input, and is "correct" in that sense.

Answer E,, is public static <T> List <? super T> backwards(List <T> input)

similar, but returns a list, which can contain T

or any superclass. Since it can also contain input elements, it is also "correct".



Choosing one of these alternatives will affect what the user can expect from the resulting list.

  • With the output, List<? extends T>

    it is possible to iterate over the list and assign each element to a variable of type T

    , but no elements, not even the type T

    , can be safely added to List

    . (Someone might refer to this list as List<SubT>

    and will receive ClassCastException

    when trying to get T

    how SubT

    .)

  • With the exit, List<? super T>

    it is safe to add elements to List

    if they are of type T

    . However, an item from a list can only be safely assigned to a variable of type Object

    . (Someone might refer to this list like List<Object>

    adding instances Object

    or other superclasses T

    ).

  • Using, List<T>

    you can safely assign list items to a type variable T

    and add type items to the list T

    (assuming this is a modifiable List

    implementation).

+2


a source


Since a List<T>

is List<? extends T>

also 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 supertype. Therefore, returning a List<T>

will satisfy both return types.



There are reasons to choose to return one or the other, but most importantly, they are legal.

+1


a source







All Articles