Page 1 of 1

About Question enthuware.ocpjp.v7.2.1445 :

Posted: Tue Nov 04, 2014 1:18 am
by SepticInsect
Why isn't this a valid answer?
ArrayList<String> in;
List<CharSequence> result;

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

Posted: Tue Nov 04, 2014 1:19 pm
by admin
Because there is no way to know what is the exact class of objects stored in the returned List. The method's return type is defined as List<? super E>, which means it is a super class of E (typed to String), but you don't know which super class. It could be CharSequence or it could be Object also. Since there is no way to determine the correct class of objects stored in the returned List, the compiler prevents you from adding any type of object in it.

HTH,
Paul.

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

Posted: Wed Nov 05, 2014 1:27 am
by SepticInsect
Thanks for the explanation. Now I understand.

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

Posted: Thu Dec 11, 2014 11:05 pm
by rocky_bgta
ArrayList<String> in;
List<Object> result;

Is this allowed ?

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

Posted: Thu Dec 11, 2014 11:07 pm
by admin
Try it out :)

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

Posted: Fri Jan 23, 2015 3:23 pm
by Svetopolk
Sorry, my question can be off topic, but these generics drives me crazy.

I changed <? super E> into <? extends E>
But List<String> result; doesn' work anyway.
Error: Type mismatch: cannot convert from List<capture#1-of ? extends String> to List<String>
But something that extends String is String. Why does it not work without cast?

Code: Select all

public class Collect {
	public static void main(String[] args) {
		ArrayList<String> in = null;
		List<String> result;
		result = doIt(in);
	}
	public static <E extends CharSequence> List<? extends E> doIt(List<E> nums) {
		return nums;
	}
}

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

Posted: Fri Jan 23, 2015 10:20 pm
by admin
Yes, something that extends String is a String (ignoring for a moment the fact that String is final) but that is only for the purpose of using that object. Not for the purpose of producing that object. For example, if you have a List of SportsCar, anything you take out of it can be used a Car. Someone can create a List of SportsCar and pass it on to you as a List of something that extends Car. Now, you don't know that it is a list of SportsCars, but actually it is. So when you try to put something into that list, you can't put a Car into it because that will mess up the List with objects that are not SportsCar.

This has also been explained here: viewtopic.php?f=2&t=473

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

Posted: Fri Jul 31, 2015 1:03 pm
by colmkav
I am a bit confused by the last sentence in the explanation:

"the only way to accomplish this is to either use non-typed reference type, such as:  List result; or use the same type as the return type mentioned in the method signature i.e. List<? super String> (because E will be bound to String in this case.)"

From what I can tell, "List result" is the only possible declaration (without casting) but this sentence above suggests List<? super String> would work (but it does not in my test if I am understanding the sentence correctly)

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

Posted: Sun Aug 16, 2015 4:43 pm
by colmkav
why doesn't this work?

public class GenericsTest {

public static void main(String[] args) {
ArrayList<String> in = null;
ArrayList<? super String> result = null;
result = doIt(in);
}

public static <E extends CharSequence> List <? super E> doIt(List<E> nums) {
return nums;
}
}

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

Posted: Sun Aug 16, 2015 8:59 pm
by admin
What does the compiler say?

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

Posted: Mon Aug 17, 2015 3:31 am
by colmkav
admin wrote:What does the compiler say?
ok, I see that I made the return type an arrayList rather than List so I understand why they aren't compatible.

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

Posted: Wed Jun 01, 2016 12:42 am
by pfilaretov
Can you clear it for me, please. The explanation says:
"The important concept here once the method returns, there is no way to know what is the exact class of objects stored in the returned List. So you cannot declare out in a way that ties it to any particular class, not even Object."
But why I can't declare

Code: Select all

List<Object> result;
Yes, I understand that the exact class of objects stored in the returned List is unknown. But it doesn't matter - it is Object anyway. What I've missed?

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

Posted: Wed Jun 01, 2016 12:44 am
by admin
I would suggest you to go through this post: viewtopic.php?f=2&t=473 I think it will be clear what you missed.

HTH,
Paul.

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

Posted: Thu Jun 02, 2016 1:29 am
by pfilaretov
I read it several times and as far as I understand the answer to my question should be like this.
Let's assume that E=String so "doIt" method returns List<? super String> which means "list of something that is a superclass of String but you don't know what exactly". List of Strings? May be. List of Objects? Probably. But you don't know.

So I can't declare

Code: Select all

List<Object> result;
because actual result may be the list of Strings and than I have a chance to put something (actually anything) to the list of Strings - that's not good!

That's the point I missed. That's why I can't do this (without explicit cast):

Code: Select all

List<String> stringList = null;
List<Object> objectList = null;
objectList = stringList;
Thanks Paul!

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

Posted: Thu Jun 02, 2016 4:41 am
by admin
You got it :)