If you call the method with
List<
String> ll = ...;
Collection<String> resultList = getLongWords(ll);
Then as per the contract of the method which is
<E extends CharSequence> Collection
<? extends CharSequence> getLongWords(Collection<E> coll)
the method can return any Collection which contains elements of any sub-type of CharSequence. String is a sub-type of CharSequence but the method says that it can return a Collection of any sub-type of CharSequence. So you cannot assume that it will return a collection of Strings.
But if you change the return type of the method to
<E extends CharSequence> Collection<E> getLongWords(Collection<E> coll)
Then calling the method with
List<String> ll = ...;
Collection<String> resultList = getLongWords(ll);
This time the compiler knows that the return type of the method is E. And since in this invocation E is String (as you passing List<String>
, so it will allow you to assign the returning value from the method to Collection<String>.