Wildcard (Java)In the Java programming language, the wildcard Covariance for generic typesUnlike arrays (which are covariant in Java[2]), different instantiations of a generic type are not compatible with each other, not even explicitly.[2] For example, the declarations This incompatibility can be softened by the wildcard if Wildcard as parameter typeIn the body of a generic unit, the (formal) type parameter is handled like its upper bound (expressed with Sample code for the class Generic <T extends UpperBound> {
private T t;
void write(T t) {
this.t = t;
}
T read() {
return t;
}
}
Sample code that uses the ...
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
...
Bounded wildcardsA bounded wildcard is one with either an upper or a lower inheritance constraint. The bound of a wildcard can be either a class type, interface type, array type, or type variable. Upper bounds are expressed using the extends keyword and lower bounds using the super keyword. Wildcards can state either an upper bound or a lower bound, but not both. Upper boundsAn upper bound on a wildcard must be a subtype of the upper bound of the corresponding type parameter declared in the corresponding generic type.[5] An example of a wildcard that explicitly states an upper bound is:
This reference can hold any parameterization of Lower boundsA wildcard with a lower bound, such as
can hold any parameterization of Object creation with wildcardNo objects may be created with a wildcard type argument: for example, However, In an array creation expression, the component type of the array must be reifiable as defined by the Java Language Specification, Section 4.7. This entails that, if the component type of the array has any type arguments, they must all be unbounded wildcards (wildcards consisting of only a For both cases, using no parameters is another option. This will generate a warning since it is less type-safe (see Raw type). Example: ListsIn the Java Collections Framework, the class public void doSomething(List<? extends MyClass> list) {
for (final MyClass object : list) { // OK
// do something
}
}
However, it is not guaranteed that one can add any object of type public void doSomething(List<? extends MyClass> list) {
final MyClass m = new MyClass();
list.add(m); // Compile error
}
The converse is true for lower bounds, which are specified using public void doSomething(List<? super MyClass> list) {
final MyClass m = new MyClass();
list.add(m); // OK
}
However, it is not guaranteed that one can iterate over that list using a variable of type public void doSomething(List<? super MyClass> list) {
for (final MyClass object : list) { // Compile error
// do something
}
}
In order to be able to do both add objects of type 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.[5] See also
Citations
References
|
Portal di Ensiklopedia Dunia