Content deleted Content added
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). |
→Example: Lists: Remove final keyword for function parameters |
||
(12 intermediate revisions by 5 users not shown) | |||
Line 1:
{{about|Java|the character|wildcard character}}
== Covariance for generic types ==
Unlike arrays (which are [[Covariance and contravariance (computer science)#Covariant arrays in Java and C#|covariant]] in Java{{sfn|Bloch|2018|loc=Chapter §5 Item 26: Don't use raw types|pp=117-122}}), different instantiations of a generic type are not compatible with each other, not even explicitly.{{sfn|Bloch|2018|loc=Chapter §5 Item 26:
This incompatibility
== Wildcard as parameter type ==
In the body of a generic unit, the (formal) type parameter is handled like its [[bounded quantification|upper bound]] (expressed with <code>'''extends'''</code>; <code>Object</code> if not constrained).{{sfn|Bloch|2018|loc=Chapter §5 Item 31: Use bounded wildcards to increase API flexibility|pp=139-145}} If the return type of a method is the type parameter, the result (e.g. of type <code>?</code>) can be referenced by a variable of the type of the upper bound (or <code>Object</code>). In the other direction, the wildcard fits no other type, not even <code>Object</code>: If <code>?</code> has been applied as the formal type parameter of a method, no actual parameters can be passed to it. However, objects of the unknown type can be read from the generic object and assigned to a variable of a supertype of the upperbound.
Sample code for the <code>Generic<T '''extends''' UpperBound></code> class:
<syntaxhighlight lang="
class Generic <T extends UpperBound> {
private T t;
Line 21 ⟶ 23:
}
}
</syntaxhighlight>
Sample code that uses the <code>Generic<T '''extends''' UpperBound></code> class:
<syntaxhighlight lang="java">
...
final Generic<UpperBound> concreteTypeReference = new Generic<UpperBound>();
final Generic<?> wildcardReference = concreteTypeReference;
final UpperBound ub = wildcardReference.read(); // Object would also be OK
wildcardReference.write(new Object()); // type error
wildcardReference.write(new UpperBound()); // type error
concreteTypeReference.write(new UpperBound()); // OK
...
</syntaxhighlight>
== Bounded wildcards ==
A bounded wildcard is one with either an upper or a lower [[Inheritance (object-oriented programming)|inheritance]] constraint. The
=== Upper bounds ===
An upper bound on a wildcard must be a subtype of the upper bound of the corresponding type parameter declared in the corresponding generic type.{{sfn|Bloch|2018|loc=Chapter §5 Item 31: Use bounded wildcards to increase API flexibility|pp=139-145}} An example of a wildcard that explicitly states an upper bound is:
<code>Generic<? '''extends''' SubtypeOfUpperBound> referenceConstrainedFromAbove;</code>
This reference can hold any
=== Lower bounds === A wildcard with a lower bound, such as <code>Generic<? '''super''' SubtypeOfUpperBound> referenceConstrainedFromBelow;</code>
can hold
== Object creation with wildcard ==
No objects may be created with a wildcard type
However, <code>new
For both cases, using no parameters is another option. This will generate a warning since it is less type-safe (see [[Raw type]]).
== Example:
In the Java Collections Framework, the class <code>List<MyClass></code> represents an ordered collection of objects of type <code>MyClass</code>.
Upper bounds are specified using <code>'''extends'''</code>:
A <code>List<? '''extends''' MyClass></code> is a list of objects of some subclass of <code>MyClass</code>, i.e. any object in the list is guaranteed to be of type <code>MyClass</code>, so one can iterate over it using a variable of type <code>MyClass</code><ref>[[Inheritance (object-oriented programming)]]</ref>
<syntaxhighlight lang="
public void doSomething(List<? extends MyClass> list) {
for (final MyClass object : list) { // OK
// do something
}
Line 65 ⟶ 78:
</syntaxhighlight>
However, it is not guaranteed that one can add any object of type <code>MyClass</code> to that list:
<syntaxhighlight lang="
public void doSomething(List<? extends MyClass> list) {
final MyClass m = new MyClass();
list.add(m); // Compile error
}
</syntaxhighlight>
The converse is true for lower bounds, which are specified using <code>'''super'''</code>:
A <code>List<? '''super''' MyClass></code> is a list of objects of some superclass of <code>MyClass</code>, i.e. the list is guaranteed to be able to contain any object of type <code>MyClass</code>, so one can add any object of type <code>MyClass</code>:
<syntaxhighlight lang="
public void doSomething(List<? super MyClass> list) {
final MyClass m = new MyClass();
list.add(m); // OK
}
</syntaxhighlight>
However, it is not guaranteed that one can iterate over that list using a variable of type <code>MyClass</code>:
<syntaxhighlight lang="
public void doSomething(List<? super MyClass> list) {
for (final MyClass object : list) { // Compile error
// do something
}
Line 89 ⟶ 102:
</syntaxhighlight>
In order to be able to do both add objects of type <code>MyClass</code> to the list and iterate over it using a variable of type <code>MyClass</code>, a <code>List<MyClass></code> is needed, which is the only type of <code>List</code> that is both <code>List<? '''extends''' MyClass></code> and <code>List<? '''super''' MyClass></code>.<ref>[[Java syntax|Java syntax(Generics)]]</ref>
The mnemonics PECS (Producer Extends, Consumer Super) from the book '''Effective Java''' by [[Joshua Bloch]] gives an easy way to remember when to use wildcards (corresponding to Covariance and Contravariance) in Java.{{sfn|Bloch|2018|loc=Chapter §5 Item 31: Use bounded wildcards to increase API flexibility|pp=139-145}}
==See also==
Line 99 ⟶ 112:
* [[Generics in Java#Type wildcards]] section explains lower and upper wildcard bounds
==
{{Reflist}}
== References ==
*{{cite book | title= "Effective Java: Programming Language Guide" |last=Bloch| first=Joshua| publisher=[[Addison-Wesley]] | edition=third | isbn=978-0134685991| year=2018}}
* The Java Language Specification, Third Edition (Sun), {{ISBN|978-0-321-24678-3}} http://java.sun.com/docs/books/jls/
* Java Tutorials, Lesson Generics http://download.oracle.com/javase/tutorial/java/generics/index.html
|