Page 1 of 1

enthuware.ocpjp.v11.2.3097 Need clarification

Posted: Thu Apr 15, 2021 7:59 pm
by ketank
In theroy associated with this question, it says
List<? super Number> is a sub type of List<? super Integer>.
A. List<? super Number> is a list of Number or its super types.
B. List<? super Integer> is a list of Integer or its super types.

How come A is sub type of B where the object type hierarchy for A is starting from Number (super to Integer) and for B its starting from Integer and yet A is a sub type of B ?

Also, could you pls provide co-relation between the theory n each option given for the question as to why its correct or incorrect and if its incorrect which step(given in theory) its failing at.

Thanks !

Re: enthuware.ocpjp.v11.2.3097 Need clarification

Posted: Thu Apr 15, 2021 11:05 pm
by admin
That's the rule. As explained in the explanation:

Hierarchy 2 : A<T> <<< A<? super T> <<< A<? super S>
Example: List<Number> is a subtype of List<? super Number> and List<? super Number> is a subtype of List<? super Integer>
Thus, if an overridden method returns List<? super Number>, the overriding method can return List<Number> but not List<Integer> or List<? super Integer>.

The reason why it is so is because of the types of objects that List<Number> and List<? super Number> can hold. List<Number> can only hold objects of type Number (such as Integer, Double etc.) while List<? super Number> means that it is a List that holds objects that are assignable to some super type of Number. Thus, a List<? super Number> could be holding not just Number but any object (because Object is a super class of Number). See this if you are not clear on this: viewtopic.php?f=2&t=473

Thus, List<Number> is more specific than List<? super Number> and therefore is considered a subtype of List<? super Number>.


Reasoning for Option 1 and 2:
It will not compile because HashSet<String> cannot be converted to Collection<T>. For example, what if while invoking the transform method, T is typed to Integer like this:

Code: Select all

Derived d = new Derived();
List<Integer> list = new ArrayList<Integer>();
Collection<Integer> c = d.transform(list); 
You would expect it to work as per the transform method signature. But it will not work if the code in the transform method returns a Collection of Strings!

Reasoning for Option 6 and 7:
Remember that generic type information is removed at runtime. So, at runtime the method at //5 actually looks like ///public Collection transform(Collection list)///, which is exactly the same as how the method in the base class will look like at runtime to the JVM. Thus, this should be a valid override. However, to the compiler, the two methods have different signatures (but same name) and constitute a valid overload.
This contradiction is not acceptable and is actually prohibited by the Java language and so //5 doesn't compile. It is neither considered a valid overload nor a valid override.

The rest are already explained.

Please go through the theory given at the end of the question carefully.

Explaining everything about generics is not really possible in forum post because there is too much to cover. So, I would suggest you to go through a good book or tutorial to master this topic.

HTH,
Paul.

Re: enthuware.ocpjp.v11.2.3097 Need clarification

Posted: Fri Apr 16, 2021 8:41 am
by ketank
Thank you for the detailed clarification. Its clear to me now.
Thanks again !