Enthuware question:
Consider the following code:
How can 'm' be declared such that the above code will compile and run without errors?
Below are the choices and the ones I picked are in
bold
Map m = new TreeMap();
Map<Object, Object> m = new TreeMap<Object, Object>();
Map<Object, ?> m = new LinkedHashMap<Object, Object>();
Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>(); will work if lines //2 and //3 are commented out.
Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>(); will work if lines //1 and //3 are commented out.
Map m = new HashMap();
According to Enthuware,
Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>(); will work if lines //1 and //3 are commented out
is incorrect because
[please note my commentary in red bold]
Map<Object, ? super ArrayList> m = new LinkedHashMap<Object, ArrayList>();
You should read it aloud as follows: 'map' 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.) [but I thought the value cannot be a subclass of ArrayList as this is generics, not using regular arrays] . However, 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. So option 4 is correct but 5 is wrong.
Thus, you can do: m.add(anyObj, new ArrayList());
So if I understand correctly the code must explicitly say
ArrayList extends Object
I am really really confused!
Then, Enthuware gives another explanation which puzzles me even more:
Just the opposite of super is extends. Consider the following method:
public void m1(List<? extends Number> list)
{
list.add(new Integer(10)); //Error at compile time because the compiler
//only knows that list contains Number or its subclas objects. But it doesn't know the exact type.
//Therefore, it will not allow you to add anything to it.
Number n = l.get(1); //This will work because the compiler knows that every object in list IS-A Number.
}
So how would we explicitly specify that Integer IS-A Number. Or is this having to do with Wrappers and Autoboxing?
Please help!