SCJP6
Robert O'Leary wrote:This is from K&B MasterExam C:
Given that String extends java.lang.CharSequence
A) public static <E extends CharSequence> Collection<? extends CharSequence>
getLongWords(Collections <E> coll)
(B) public static <E extends CharSequence> List<E> getLongWords(Collection<E> coll)
(C) public static Collection<E extends CharSequence> getLongWords(Collection<E> coll)
(D) public static List<CharSequence> getLongWords(Collection<CharSequence> coll)
(E) public static List<? extends CharSequence> getLongWords(Collection<? extends CharSequence> coll)
(F) static public <E extends CharSequence> Collection<E> getLongWords(Collection<E> coll)
(G) static public <E super CharSequence> Collection<E> getLongWords(Collection<E> coll)
Correct answer is F. I can see why it is, but I have a question about (A) and (G):
Q1) For the reference to the answer, K&B say that the return type in (A) is too vague. Is that is must be Collection<String>, no polymorphic wiggle-room??
Q2) For (G), I know that super can never be used in a generic type declaration as above, but why?
I dont know if helps anyone else when I was tryin to figure out this Q, I found it easier to answer it by writing down what is legal for each piece of the method declaration and then eliminate (A) - (G) accordingly:
1) Generic Type Declaration (after public static in each answer)
<E>
<E extends CharSequence>
<E extends String> //pointless but legal
2) Return type
Collection<E>
3) Method parameter
Collection<E> coll
List<E> coll
Why do ye think?
All code in my posts, unless a source is explicitly mentioned, is my own.
Ruben Soto wrote:
In A. you have:
public static <E extends CharSequence> Collection<? extends CharSequence>
getLongWords(Collections <E> coll)
When you call the method, you are calling it using an argument that is a List<String>. This means that E is resolved to String (no problem there.) The problem is that you are assigning the return of your method to a Collection<String>, and you are returning a collection of a type which extends CharSequence (but which might not be String.) That's why A is illegal.
Ruben Soto wrote:
The reason why you can't use <E super X> is because it is illegal. And the reason why it is illegal is because it is of no use, because it doesn't impose any upper bounds on the type, which is what you care about, because upper bounds are what the compiler uses when applying type erasure. If you have <E extends X>, then upon type erasure, the compiler will insert a cast to type X wherever a reference of the generic type E is used, because E Is-A X. But <E super X> doesn't have any use, so it is illegal.
SCJP6
All code in my posts, unless a source is explicitly mentioned, is my own.