About Question enthuware.ocpjp.v8.2.1445 :

Help and support on OCA OCP Java Programmer Certification Questions
1Z0-808, 1Z0-809, 1Z0-815, 1Z0-816, 1Z0-817

Moderator: admin

ninjafox
Posts: 2
Joined: Fri May 21, 2021 6:30 am
Contact:

Re: About Question enthuware.ocpjp.v8.2.1445 :

Post by ninjafox »

One of the rules is that a generic type can't inherit another generic type. There is simply no relation between them

Code: Select all

List<Object> list = new ArrayList<String>(); // Compilation error
In the code above, we assume that since String is a subclass of Object, we are allowed to assign an object of type ArrayList<String> to a reference of type List<Object>. However, this is not true. Try to look at the variable of type List<Object> as an independent type. For instance, the object of type String can be assigned to a variable of type Object thanks to inheritance. But the object of type List<String> can't be assigned to a variable of type List<Object>, because generic types do not support inheritance. The super type and the sub type of any generic type is the generic type itself. Hence, only the following assignments are allowed

Code: Select all

List<Object> list = new ArrayList<Object>(); // OK
List<String> list = new ArrayList<String>(); // OK
List<Object> list = new ArrayList<>(); // OK since Java 1.7 (ArrayList<> here is implicitly ArrayList<Object>)
We may still apply inheritance when dealing with elements in a generic collection

Code: Select all

List<Object> list = new ArrayList<>();
list.add(new Object());
list.add(new String());
list.add(new StringBuilder());
Now, as for the method in the question

Code: Select all

public static <E extends CharSequence> List<? super E> doIt(List<E> nums) {...}
<E extends CharSequence> means "Some type E that implements CharSequence", which can be String, StringBuilder, StringBuffer, etc. Thus, we may pass List<String>, List<StringBuilder> and List<StringBuffer> to the method. Now we want to get the result from the method, and logically we may think that the List<Object> can hold anything we want, so we go on with the code like this

Code: Select all

List<String> listOfStrings = new ArrayList<>();
List<Object> result = doIt(listOfStrings); // Compilation error
This code fails because a variable of type List<Object> expects only an object of type List<Object>. The method states that it returns List<? super E>. That is "Any type that is a parent to type E (that implements CharSequence) or E itself". Can it be List<Object>? Yes, it can. But can it also be List<String>? Or List<StringBuilder>? Yes, it can. And as we already know Java can't allow an object of type List<String> to be assigned to a variable of type List<Object>. Hence the only three variable types that are allowed to hold a reference to List<? super E> are these

Code: Select all

List result1 = doIt(listOfStrings); // raw type can be of any type
List<?> result2 = doIt(listOfStrings); // <?> means anything 
List<? super String> result3 = doIt(listOfStrings); // bounded type does not violate the return type of the method
If you want to dive deep, read about covariant, contravariant and invariant types

basileu1
Posts: 2
Joined: Tue Aug 10, 2021 8:37 am
Contact:

Re: About Question enthuware.ocpjp.v8.2.1445 :

Post by basileu1 »

Hi,

If may I add my 2 cents on the crux of the topic. It has to do with polymorphism of types of generics.
If this does not compile:

Code: Select all

	List<Object> myObjects = new ArrayList<String>();
then this also cannot compile

Code: Select all

        ArrayList<String> in = new ArrayList<>();
        List<Object> result = doIt(in);

Post Reply

Who is online

Users browsing this forum: No registered users and 37 guests