Creating an instance of a generic class of type <?>
I am participating in SCJP / OCPJP and I came across a sample question that seems strange to me.
The sample code instantiated two common 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 any collection would result in a runtime error.
When I try to compile such code, I just get errors. The Java tutorial doesn't even show this type of code; instead, it usually uses wildcards as part of the upcast.
Collection<?> c = new ArrayList<String>(); Are two common collections above even legal code? The second one in my logic will only prohibit interfaces. The first looks completely useless. Why use a common element that is not trying to control?
Check out this great Java Java tutorial . More specifically, the wildcard section contains the answer to your question, and I quote
Collection<?> c = new ArrayList<String>(); c.add( new Object() ); Since we do not know what the type of element
cmeans, we cannot add objects to it. Theadd()method accepts arguments of typeE, the type of the item in the collection. When is the actual type parameter?, it means some unknown type. Any parameter that we pass to add will have to be a subtype of this unknown type. Since we do not know what type, that is, we can not convey anything. The one exception isnull, which is a member of each type.
If you want to declare Type at runtime, you can do something like this:
public class Clazz1<T> { private final List<T> list = new ArrayList<T>(); private List<T> getList() { return list; } /** * @param args */ public static void main(String[] args) { Clazz1<Integer> clazzInt = new Clazz1<Integer>(); clazzInt.getList().add(2); System.out.println(clazzInt.getList()); Clazz1<String> clazzString = new Clazz1<String>(); clazzString.getList().add("test"); System.out.println(clazzString.getList()); } } I answered this a bit earlier in this answer. ? cannot be used in an instance. I'm not sure why he says the code will compile, none of the java compilers I used would allow this. You can do what is shown above:
List<?> list = new ArrayList(); This will compile and run, but you will not be able to:
list.add("hello world"); //This wouldn't compile