Is there ever a difference between an unbounded wildcard e.g. <?>
and a bounded wildcard whose bound is Object
, e.g. <? extends Object>
?
I recall reading somewhere that there was a difference in the early drafts of generics, but cannot find that source anymore.
It is complicated...
For any type variable
T
, the spec says http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.4One would think that it's true for wildcard too, and
?
should just be a shorthand for? extends Object
.Yet searching through the spec, there is no evidence at all that a wildcard must have an upper bound (or lower bound). The "unbounded"
?
is treated consistently distinctly from bounded wildcards.We could deduce from subtyping rules, that
List<?>
andList<? extends Object>
are subtypes of each other, i.e., they are basically the same type.But the spec treats them separately nevertheless. For example http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.7
List<?>
is a reifiable type, butList<? extends Object>
is not, which meansI don't understand why though. It seems perfectly fine to say a wildcard must have an upper bound and a lower bound, default to
Object
andnull type
.<? extends Object>
is EXACTLY the same as<?>
. I'm sorry I don't have a reference handy, but ... it is. :)EDIT: of course, I was only thinking from a particular perspective when I said that. Ignore my answer (which was quite correctly downvoted) and see the higher-rated answers for the real story.
As a point of pedntry, there is a difference if the class/interface/constructor/method declares a bound (other than
extends Object
).From a practical point to most people,
<? extends Object>
is the same as<?>
, like everyone have suggested here.However, they differ in two very minor and subtle points:
The JVMS (Java Virtual Machine Specification) has a special specification for the unbounded wildcards, as
ClassFileFormat-Java5
specifies that unbounded wildcard gets encoded as*
, while encodes a Object-bounded wildcard as+Ljava/lang/Object;
. Such change would leak through any library that analyzes the bytecode. Compiler writers would need to deal with this issue too. From revisions to "The class File Format"From reifiablity standpoint, those are different. JLS 4.6 and 4.7 codify
List<?>
as a reifiable type, butList<? extends Object>
as a erasured type. Any library writer adding.isReifiable()
(e.g. mjc lib) needs to account for that, to adhere to the JLS terminology. From JLS 4.6 and 4.7.Everything in java with the exception of primitives extend Object, so no, there would be no difference. Autoboxing allows the use of primitives so it could be said everything in java is an object.
From experimentation it seems that, for example,
List<?>
andList<? extends Object>
are assignment-compatible both ways, and a method that has a signature using one of them can be overridden with a signature using the other. e.g.,