Wildcard (Java)
Encyclopedia
The wildcard
is a special actual parameter for the instantiation of generic
(parameterized) types. It can be used for the instantiation, not in the definition of a generic unit. This article summarizes the most important rules for its use.
This incompatibility may be softened by the wildcard if
(expressed with
This reference can hold any instantiation of
can hold instantiations of
It is even possible to constrain a reference's compatibility from both sides: from above by a generic class or method definition (
On the other hand, an array object that is an array of a parameterized type may be created only by an unconstrained (i.e. with wildcard type parameter) type (and by no other instantiations) as the component type:
An example of using wildcard in List's instantiation is contained in the article Generics in Java
.
Upper bounds are specified using
A
However, it is not guaranteed that one can add any object of type
The converse is true for lower bounds, which are specified using
A
However, it is not guaranteed that one can iterate over that list using a variable of type
In order to be able to do both add objects of type
?
in JavaJava (programming language)
Java is a programming language originally developed by James Gosling at Sun Microsystems and released in 1995 as a core component of Sun Microsystems' Java platform. The language derives much of its syntax from C and C++ but has a simpler object model and fewer low-level facilities...
is a special actual parameter for the instantiation of generic
Generics in Java
Generics are a facility of generic programming that was added to the Java programming language in 2004 as part of J2SE 5.0. They allow "a type or method to operate on objects of various types while providing compile-time type safety." A common use of this feature is when using a Java Collection...
(parameterized) types. It can be used for the instantiation, not in the definition of a generic unit. This article summarizes the most important rules for its use.
Covariance for generic types
Unlike arrays (which are covariant in Java), different instantiations of a generic type are not compatible to each other, not even explicitly: With the declarationGeneric superGeneric; Generic subGeneric;
the compiler would report a conversion error for both castings (Generic)superGeneric
and (Generic)subGeneric
.This incompatibility may be softened by the wildcard if
?
is used as actual type parameter: Generic>
is the abstract supertype for all instantiations of the generic type. It means, no objects of this type may be created, only variables. The usage of such a variable is to refer to instantiations of Generic
with any actual type parameter.Wildcard as parameter type
In the body of a generic unit, the (formal) type parameter is handled like its upper boundBounded quantification
In type theory, bounded quantification refers to universal or existential quantifiers which are restricted to range only over the subtypes of a particular type. Bounded quantification is an interaction of parametric polymorphism with subtyping...
(expressed with
extends
; Object
if not constrained). If the return type of a method is the type parameter, the result (e.g. of type ?
) can be referenced by a variable of the type of the upper bound (or Object
). In the other direction, the wildcard fits to no other type, not even to Object
: If ?
has been applied for the formal parameter of a method, no actual parameters can passed to it. It can be called only by casting of the wildcard reference:Wildcard constraints
Not only the formal type parameters in the generic unit, also the wildcard can be (further) constrained if one doesn't want to be compatible to all instantiations:Generic extends SubtypeOfUpperBound> referenceConstrainedFromAbove;
This reference can hold any instantiation of
Generic
with an actual type parameter of SubtypeOfUpperBound
's subtype. A wildcard that does not have a constraint is effectively the same as one that has the constraint extends Object
, since all types implicitly extend Object. A constraint with a lower boundGeneric super SubtypeOfUpperBound> referenceConstrainedFromBelow;
can hold instantiations of
Generic
with any supertype (e.g. UpperBound
) of SubtypeOfUpperBound
. (Such a wildcard still has an implicit upper bound of Object
.)It is even possible to constrain a reference's compatibility from both sides: from above by a generic class or method definition (
extends UpperBound>
), or from below by the reference declaration ( super SubtypeOfUpperBound>
).Object Creation with Wildcard
No objects may be created with a wildcard type parameter(new Generic>
is forbidden because Generic>
is abstract). In practice, this is unnecessary because if one wanted to create an object that was assignable to a variable of type Generic>
, one could simply use any arbitrary type (that falls within the constraints of the wildcard, if any) as the type parameter.On the other hand, an array object that is an array of a parameterized type may be created only by an unconstrained (i.e. with wildcard type parameter) type (and by no other instantiations) as the component type:
new Generic>[20]
is correct, while new Generic[20]
is prohibited.An example of using wildcard in List's instantiation is contained in the article Generics in Java
Generics in Java
Generics are a facility of generic programming that was added to the Java programming language in 2004 as part of J2SE 5.0. They allow "a type or method to operate on objects of various types while providing compile-time type safety." A common use of this feature is when using a Java Collection...
.
Example: Lists
In the Java Collections Framework, the classList
represents an ordered collection of objects of type MyClass
.Upper bounds are specified using
extends
:A
List extends MyClass>
is a list of objects of some subclass of MyClass
, i.e. any object in the list is guaranteed to be of type MyClass
, so one can iterate over it using a variable of type MyClass
However, it is not guaranteed that one can add any object of type
MyClass
to that list:The converse is true for lower bounds, which are specified using
super
:A
List super MyClass>
is a list of objects of some superclass of MyClass
, i.e. the list is guaranteed to be able to contain any object of type MyClass
, so one can add any object of type MyClass
:However, it is not guaranteed that one can iterate over that list using a variable of type
MyClass
:In order to be able to do both add objects of type
MyClass
to the list and iterate over it using a variable of type MyClass
, a List
is needed, which is the only type of List
that is both List extends MyClass>
and List super MyClass>
.