I'm studying for the SCJP/OCPJP and I came across a sample question that seams strange to me.
The sample code instantiated two generic collections:
List<?> list = new ArrayList<?>();
List<? extends Object> list2 = new ArrayList<? extends Object>();
The "correct" answer to the question was that this code would compile but adding to either collection would produce a runtime error.
When I try to compile code like this I just get errors. The Java tutorial does not even show this type of code, it instead usually uses wildcards as a part of an upcast.
Collection<?> c = new ArrayList<String>();
Are the two generic collections above even legitimate code? The second by my logic would only disallow interfaces. The first one looks completely useless. Why use a generic that makes no attempt at control?
Check out the excellent Java generics tutorial PDF. More specifically the section about wildcards contains the answer to your question, and I quote
Collection<?> c = new ArrayList<String>();
c.add( new Object() );
Since we don’t know what the element type of
c
stands for, we cannot add objects to it. Theadd()
method takes arguments of typeE
, 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 isnull
, which is a member of every type.