Wildcard (Java): Difference between revisions

Content deleted Content added
Hamsooper (talk | contribs)
Corrected error in introduction. Wildcards were called "type parameters" when, technically speaking they are not type parameters but rather type arguments (see section 4.5.1 of the JLS).
Hamsooper (talk | contribs)
Fixed several instances where type arguments were mistakenly called type parameters. Removed a phrase where the parameterized type "Generic<?>" was called abstract, which it is not (in the sense defined by the JLS). Gave the "Bounded Wildcards" section subsections for upper and lower bounds.
Tags: references removed Visual edit
Line 5:
Unlike arrays (which are [[Covariance and contravariance (computer science)#Covariant arrays in Java and C#|covariant]] in Java), different instantiations of a generic type are not compatible with each other, not even explicitly: With the declaration <code>Generic<Supertype> superGeneric; Generic<Subtype> subGeneric;</code> the compiler would report a conversion error for both castings <code>(Generic<Subtype>)superGeneric</code> and <code>(Generic<Supertype>)subGeneric</code>.
 
This incompatibility may be softened by the wildcard if <code>?</code> is used as an actual type parameter: <code>Generic<?></code> is the abstracta supertype forof all parameterizarions of the generic type <code>Generic</code>. This allows objects of type <code>Generic<Supertype></code> and <code>Generic<Subtype></code> to be safely assigned to a variable or method parameter of type <code>Generic<?></code>. Using <code>Generic<? extends Supertype></code> allows the same, restricting compatibility to <code>Supertype</code> and its children. Another possibility is <code>Generic<? super Subtype></code>, which also accepts both objects and restricts compatibility to <code>Subtype</code> and all its parents.
 
== Wildcard as parameter type ==
Line 32:
== Bounded wildcards ==
 
A bounded wildcard is one with either an upper or a lower [[Inheritance (object-oriented programming)|inheritance]] constraint. The boundsbound of a wildcard can be botheither a class andtype, interface typestype, array type, or type variable. Upper bounds are expressed using the '''extends''' keyword and lower bounds using the '''super''' keyword.

=== Upper bounds ===
An upper bound on a wildcard must be a subtype of the upper bound onof the corresponding type parameter declared itin isthe assignedcorresponding generic type. An example of a wildcard that explicitly states an upper bound is:
 
<code>Generic<? '''extends''' SubtypeOfUpperBound> referenceConstrainedFromAbove;</code>
 
This reference can hold any instantiationparameterization of <code>Generic</code> withwhose antype actualargument typeis parametera subtype of <code>SubtypeOfUpperBound</code>'s subtype. A wildcard that does not haveexplicitly state an upper bound is effectively the same as one that has the constraint <code>extends Object</code>, since all reference types implicitlyin extendJava are subtypes of Object.

=== Lower bounds ===
A wildcard with a lower bound, such as
 
<code>Generic<? '''super''' SubtypeOfUpperBound> referenceConstrainedFromBelow;</code>
 
can hold instantiationsany parameterization of <code>Generic</code> withwhose any type thatargument is both a subtype of <code>UpperBound</code>the corresponding type parameter's upper bound and a supertype of <code>SubtypeOfUpperBound</code>. The type bounds are trivial examples that conform.
 
== Object creation with wildcard ==
 
No objects may be created with a wildcard type parameterargument: for example, <code>'''new''' Generic<?>()</code> is forbidden because <code>Generic<?></code> is abstract.<ref>{{citation|title=The Java Language Specification|section=Class Instance Creation Expressions|url=http://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.9|publisher=Oracle}}</ref> In practice, this is unnecessary because if one wanted to create an object that was assignable to a variable of type <code>Generic<?></code>, one could simply use any arbitrary type (that falls within the constraints of the wildcard, if any) as the type parameterargument.
 
However, <code>new ListArrayList<Generic<?>>()</code> is allowed, because the wildcard is not a parameter to the instantiated type <code>ListArrayList</code>. The same holds for <code>new ListArrayList<List<?>>()</code>.
 
AnIn an array objectcreation thatexpression, isthe ancomponent arraytype of athe parameterizedarray typemust canbe onlyreifiable parameterizedas defined by anthe unconstrainedJava (iLanguage Specification, Section 4.e7. withThis anentails unboundthat, wildcardif typethe parameter)component type asof the componentarray has any type: arguments, they must all be unbounded wildcards (wildcards consisting of only a <code>?</code>) . For example, <code>'''new''' Generic<?>[20]</code> is correct, while <code>'''new''' Generic<SomeType>[20]</code> is not.
 
For both cases, using no parameters is another option. This will generate a warning since it is less type-safe (see [[Raw type]]).
 
== Example: listsLists ==
 
In the Java Collections Framework, the class <code>List<MyClass></code> represents an ordered collection of objects of type <code>MyClass</code>.