Page 1 of 1

About Question enthuware.ocpjp.v7.2.1300 :

Posted: Tue Feb 18, 2014 1:37 pm
by EpicWestern
"Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>();

"you cannot put Object (which is a superclass of ArrayList) in it because the compiler doesn't know the exact superclass that 'map' can take. It could be AbstractList, or Object, or any other super class of ArrayList. The compiler only knows that it is a superclass but not the exact type."

At compile time it does know the exact class because the map was instantiated. Object can't be added because the type of the value is ArrayList.

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

Posted: Tue Feb 18, 2014 8:59 pm
by admin
The given explanation is correct. At compile time, only the declared type of the variable i.e. Map<Object, ? super ArrayList> is taken into consideration by the compiler. Not the type of the instantiated object.

HTH,
Paul.

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

Posted: Wed Feb 19, 2014 12:15 pm
by EpicWestern
Yes, you're correct. I thought the below worked for me, but I tried it again and it doesn't.

Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, Object>();
m.put(new Object(), new Object());

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

Posted: Thu May 29, 2014 11:58 am
by Crashtest
The explanation given below answers is horribly difficult for me.
Below, I try to "translate" it to shorter, easier for me version. Would you agree this is right?

Code: Select all

Map<Object, ?> m = new LinkedHashMap<Object, Object>();
Since we have value declared as "?" we have to treat Map values as read-only.

Code: Select all

Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>();
Since we have "? super ArrayList" we have to treat Map values as read-only for anything that is a super class of ArrayList (the "?" part of it), but if we were to use ArrayList itself, since is mentioned here explicitly, can be treaded as read-write?

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

Posted: Thu May 29, 2014 8:42 pm
by admin
Crashtest,
Yes, this is fine as a memory aid. It is not an explanation to "why" you have to treat ? as read only though.

HTH,
Paul.

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

Posted: Fri Jul 31, 2015 3:09 pm
by colmkav
Crashtest wrote:The explanation given below answers is horribly difficult for me.
Below, I try to "translate" it to shorter, easier for me version. Would you agree this is right?

Code: Select all

Map<Object, ?> m = new LinkedHashMap<Object, Object>();
Since we have value declared as "?" we have to treat Map values as read-only.

Code: Select all

Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>();
Since we have "? super ArrayList" we have to treat Map values as read-only for anything that is a super class of ArrayList (the "?" part of it), but if we were to use ArrayList itself, since is mentioned here explicitly, can be treaded as read-write?
Anything that is a superclass of ArrayList will also be read-write? or not? (assuming we change the right side to reflect this)

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

Posted: Mon Nov 23, 2015 3:50 am
by fariz.siracli
hello guys. i think this sentence from explanation is wrong:

You should read it aloud as follows: 'm' is declared to be of type Map that takes an instance of Object class as a key and an instance of 'a class that is either ArrayList or a superclass of Arraylist' as value. This means that the value can be an instance of ArrayList or its subclass (since an ArrayList object or its subclass object can be assigned to a reference of type ArrayList or its super class.).

they should be super class instead.

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

Posted: Mon Nov 23, 2015 4:53 am
by admin
No, it is correct. An object of a class that is a superclass of ArrayList cannot be assigned to a reference of type ArrayList.

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

Posted: Mon Nov 23, 2015 3:48 pm
by fariz.siracli
mister Admin look at sentence please:
'm' is declared to be of type Map that takes an instance of Object class as a key and an instance of 'a class that is either ArrayList or a superclass of Arraylist' as value. This means that the value can be an instance of ArrayList or its subclass (since an ArrayList object or its subclass object can be assigned to a reference of type ArrayList or its super class.)


First it says "is either ArrayList or its superclass" and then it says "instance of ArrayList or its subclass".

Do you find it logical ?
I mean those words in explanation are wrong, not whole explanation.

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

Posted: Mon Nov 23, 2015 7:38 pm
by admin
Yes, it is logical. It is complicated but logical.
Think about it this way - if you have a method whose parameter type is ArrayList or any of its super class (e.g. List), what type of objects can you pass to this method? Any object of class ArrayList or its subclass.

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

Posted: Wed Nov 25, 2015 1:55 am
by siarhei
hi all,
could anyone please explain why the first answer in green is correct (http://prntscr.com/96ob73):

Code: Select all

Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>();
Tried to compile the next piece of code:

Code: Select all

private void test() {
	//Map m = new HashMap();
	Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>();

	m.put("1", new ArrayList());
	m.put(1, new Object());
	m.put(1.0, "Hello");
}
As a result, there were 2 compile time errors:
  1. Code: Select all

    error: method put in interface Map<K,V> cannot be applied to given types;
    		m.put(1, new Object());
    		 ^
      required: Object,CAP#1
      found: int,Object
    
  • Code: Select all

    error: method put in interface Map<K,V> cannot be applied to given types;
    		m.put(1.0, "Hello");
    		 ^
      required: Object,CAP#1
      found: double,String
    
I think either the question condition has an error or list of answers as the question says:
the above code will compile and run without errors
Thanks

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

Posted: Wed Nov 25, 2015 2:34 am
by admin
As the option statement says, you need to first comment out lines marked //2 and //3.

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

Posted: Wed Nov 25, 2015 7:57 am
by siarhei
Thank you for reply. It's my inattention...

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

Posted: Sat Nov 28, 2015 9:57 am
by sir_Anduin@yahoo.de
Sorry Paul. I still dont understand.

isnt <? super MyClass> the lower bound, so nothing that extends MyClasscan be used?
accordingly:
<? extends MyClass> means upper bound, so nothing that is a super class of MyClass can be used

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

Posted: Sat Nov 28, 2015 10:35 am
by admin
I suggest you to go through this short write up and then revisit this question: viewtopic.php?f=2&t=473

-Paul.

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

Posted: Tue Sep 20, 2016 4:52 am
by Paulus
I found this explanation at the Java API documentation as a complement to the given description about read-only wildcards <?> (link):

Code: Select all

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error
Since we don't know what the element type of c stands for, we cannot add objects to it. The add() method takes arguments of type E, the element type of the collection. When the actual type parameter is ?, it stands for some unknown type. Any parameter we pass to add would have to be a subtype of this unknown type. Since we don't know what type that is, we cannot pass anything in. The sole exception is null, which is a member of every type.

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

Posted: Thu Sep 05, 2019 1:33 pm
by dongyingname

Code: Select all

Collection<?> c = new ArrayList<String>();
c.add(new Object()); // Compile time error
I just came up with an easiest approach to this type of question: Think like a compiler.
A compiler would guess, what if ? is Integer?
It wouldn't work. Thus failed to compile.

Code: Select all

Map<Object, ?> m = new LinkedHashMap<Object, Object>();
What if ? is String? Wouldn't work without casting a Object to String.

Code: Select all

Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>(); will work if lines //2 and //3 are commented out.
Map<Object, ? super ArrayList> would accept m.put("1", new ArrayList()) because no mater what '? super Arraylist' would be it doesn't need a explicit cast to become ArrayList.

Code: Select all

m.put(1, new Object()); //2  and m.put(1.0, "Hello");     //3 
would fail because compiler may want to try

Code: Select all

Map<Object, List> m 
In this case List is a super-class of ArrayList, but can't be an Object without a casting; it absolutely can't be a String.

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

Posted: Tue Apr 28, 2020 1:31 pm
by javabean68
Hi all,

I could understand (or at least it seems to me :shock: ) all except the line:

Code: Select all

Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>();  
It is said:
This means that the value can be an instance of ArrayList or its subclass (since an ArrayList object or its subclass object can be assigned to a reference of type ArrayList or its super class.). However, you cannot put Object (which is a superclass of ArrayList) in it because the compiler doesn't know the exact superclass that 'm' can take. It could be AbstractList, or Object, or any other super class of ArrayList. The compiler only knows that it is a superclass but not the exact type
I wonder :roll: why we then used

Code: Select all

 ? super ArrayList
at all? What for an advantage offers that instead of simply using directly ArrayList?, e.g.

Code: Select all

Map<Object, ArrayList> m = new LinkedHashMap<Object, ArrayList>();  
Thank you in advance
Bye
Fabio

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

Posted: Wed Apr 29, 2020 3:56 am
by admin
"? super ArrayList" useful when you are not instantiating the object but getting from someone else through a method call. You don't want to put a restriction on the kind of object the sender can send but you want to make sure you can put only certain kind of objects in in. For example, you can have this method:

mymethod(List<? super ArrayList> passedList){ .... }

Now, the caller is free to even send a List<Object> to this method. But you want to restrict adding only objects of ArrayList (and itssubclasses) inside the mymethod.

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

Posted: Sat May 02, 2020 9:03 am
by javabean68
Thank you!
Bye
Fabio