Win a copy of The Java Performance Companion this week in the Performance forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

Generic method invocation

 
Rachel Glenn
Ranch Hand
Posts: 95
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
So I came across this problem in the Bates and Sierra practice exam:

GIVEN:



WHICH OF THE FOLLOWING CAN BE INSERTED at //INSERT HERE to compile and run without error?

Because my brain is scrambling on this, I want to review each option and my understanding of it...

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

This option is considered correct, and I understand it.

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

This option is considered correct. First, the reason that the input can be List<? extends T> is because the method does not modify the input. Second, any subtypes of T can be added to the List<T> that is created and returned in this function. Does this sound right?

C. public static <T> List<T> backwards(List<? super T> input)


This option is INCORRECT, because the caller of this method is expecting a return reference to a List<T>, where each element in the list is type T or a subtype of T. However, the input is allowing supertypes of T, and those can't be added to the returned list because it violates the method 'contract'. Does this sound right?

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


This option is considered CORRECT. The way I read this is that the return value is a reference to a List of objects of type T or a subtype of T. The input is a list of objects of type T, therefore, they can be added to the list that gets retruned to the caller. Does my reasoning sound ok?

E. public static <T> List<? super T> backwards(List<T> input)

This option is considered CORRECT. But I am not sure if I understand fully. The way I read this is that the return value is a reference to a List of objects of type T or supertype of T. The input is guaranteed to be a list of objects that are ALL of type T, so they should be able to be added to the return list. BUT, suppose this list I pass in is declared as List<T> but contains objects that are also a supertype of T ?


Can someone explain why this option is VALID??

F. public static <? extends T> List<T> backwards(List<T> input)
G. public static <? super T> List< T> backwards(List<T> input)


I understand both OPTIONS F and G are invalid because wildcards are not allowed in the type declaration.
 
Jeanne Boyarsky
author & internet detective
Marshal
Posts: 34672
367
Eclipse IDE Java VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
For D and E, I'd explain it a little differently. Consider the following code:


This is valid because backwards returns List<Super>. I can store that List<Super> in List<? extends Super> and List<? super Super>. For this reason, the return type of the method itself could be either of these. It's just a more general return type for what you know to be returned - List<Super>.
 
Himai Minh
Ranch Hand
Posts: 1296
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Rachel Glenn wrote:So I came across this problem in the Bates and Sierra practice exam:

GIVEN:



WHICH OF THE FOLLOWING CAN BE INSERTED at //INSERT HERE to compile and run without error?

D. public static <T> List<? extends T> backwards(List<T> input)[/u]


This option is considered CORRECT. The way I read this is that the return value is a reference to a List of objects of type T or a subtype of T. The input is a list of objects of type T, therefore, they can be added to the list that gets retruned to the caller. Does my reasoning sound ok?

E. public static <T> List<? super T> backwards(List<T> input)[/u]

This option is considered CORRECT. But I am not sure if I understand fully. The way I read this is that the return value is a reference to a List of objects of type T or supertype of T. The input is guaranteed to be a list of objects that are ALL of type T, so they should be able to be added to the return list. BUT, suppose this list I pass in is declared as List<T> but contains objects that are also a supertype of T ?



For D, you pass in a list of T objects (can be T or subtype of T). The backwards method expects a list of T or subtype of T. In the code, it returns output which is a List<T>. What is expected matches with what is returned.
For E, you pass in a list of T objects. The backwards method expects a list of T or T's supertype. In the code, it returns output which is a List<T>. Wath is expected matches with what is returned.
 
Himai Minh
Ranch Hand
Posts: 1296
6
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
C is incorrect because:

Use an example, T is Animal. The input can be a list of Object. The output is a list of Animal. But output cannot add an Object to it because output can only contain Animal.
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic