Java's official documentation says:
It's important to note that
List<Object>
andList<?>
are not the same. You can insert anObject
, or any subtype ofObject
, into aList<Object>
. But you can only insertnull
into aList<?>
.
Reference link.
This does not seem to be true. These two compile well and are usable (e.g. the list elements can be printed just fine):
List<Object> l1 = Arrays.asList(null, null);
List<?> l2 = Arrays.asList(null, null);
l1.add(null);
l2.add(null);
Could you please say what the quoted sentence in the documentation really means?
CodePudding user response:
No, the text is correct. null
is a valid value for any type, therefore, you can invoke .add(null)
on any list, regardless of what is in the <?>
. However, null
(literally) is the only thing you can add to a List<? extends Whatever>
. Given that literally .add(null)
is generally useless, let's disregard it, which lets us simply state:
You cannot add anything to a List<?>
.
That's the point of what the text is trying to explain.
Why can't you add anything? Because of this:
Let's say you have a List<? extend Number>
. That means you can have a List<Integer>
, or a List<Double>
- those both 'work'. But given that you don't know what it is, if you just try to add an Integer object to this list (which is a Number), then maybe you're adding an Integer to a list of Doubles which would be an illegal move. Conclusion: .add()
on a list of <?>
or <? extends something>
is not possible. (Except for the academic case of null
).
CodePudding user response:
Your test case does not cover the statement: You're not inserting objects, you're creating lists around predefined sets of objects.
Instead try something like
List<Object> l1 = new ArrayList<>();
l1.add(null);
l1.add("foo");
List<?> l2 = new ArrayList<>();
l2.add(null);
l2.add("foo"); // <-- here we expect a compilation error