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.
both bounded and unbounded wildcards provide a lot of flexibility on API design especially because Generics is not covariant and List<String> can not be used in place of List<Object>. Bounded wildcards allow you to write methods that can operate on Collection of Type as well as Collection of Type subclasses.
8.4. An unbound generic type is not itself a type, and cannot be used as the type of a variable, argument or return value, or as a base type. The only construct in which an unbound generic type can be referenced is the typeof expression (§11.7. 16).
In the Java programming language, the wildcard ? is a special kind of type argument that controls the type safety of the use of generic (parameterized) types. It can be used in variable declarations and instantiations as well as in method definitions, but not in the definition of a generic type.
The question mark (?) is known as the wildcard in generic programming. It represents an unknown type. The wildcard can be used in a variety of situations such as the type of a parameter, field, or local variable; sometimes as a return type.
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, but List<? 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.
As a point of pedntry, there is a difference if the class/interface/constructor/method declares a bound (other than extends Object
).
interface Donkey<T extends Thing> { }
...
Donkey<? extends Object> foo; // FAIL
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With