Summary
PECS
- producer extends; consumer super
- when to use the upper/lower bounded wildcards
- producer can produce
T
so it can produce any subtype, since the base information is still there - consumer can store
T
so it can store any supertype,
Upper-bounded wildcard
?
can be substituted for a subtype ofT
- mimicking covariance
java
L<? extends A>
Lower-bounded wildcard
?
can be substituted for a supertype ofT
- mimicking contravariance
java
A<? super T>
Concept
Java generics classes are invariant
Unbounded wildcard
?
can be substituted for any type
java
L<?>
Diamond operator
- not a rawtype, has angled brackets
- makes code less verbose
- Java will figure out what types to put in
java
L<A> a = new L<>();
Type inference
- infer type argument automatically
- if there are multiple, pick the most specific one
Application
Sequence, copying
java
class Seq<T> {
...
public void copyFrom(Seq<? extends T> src) { // accepts all Seq<S> where S<:T
int len = Math.min(this.array.length, src.arracy.length);
for (int i = 0; i < len; i++ ) {
this.set(i, src.get(i)); // src is used to produce, hence extends
}
}
public void copyTo(Seq<? super T> dest) { // accepts all Seq<S> where T<:S
int len = Math.min(this.array.length, src.arracy.length);
for (int i = 0; i < len; i++ ) {
dest.set(i, this.get(i)); // something is done to dest, dest consumes, hence super
}
}
}
// Circle <: Shape
Seq<Shape> shapes = new Seq<>(1);
Seq<Circle> circles = new Seq<>(1);
shapes.copyFrom(circles); // works, Seq<Circle> <: Seq<? extends Shape>
shapes.copyTo(circles); // error, Seq<Circle> </: Seq<? super Shape>
circles.copyFrom(shapes); // error, Seq<Shape> </: Seq<? extends Circle>
circles.copyTo(shapes); // works, Seq<Shape> <: Seq<? super Circle>
Type inference, solve for constrains on T
java
...<T>
... boolean contains(T[] seq, T obj)
A.contains(stringArray, 123); // String[], Integer
java
... <T extends GetAreable>
... T findLargest(Seq<? extends T> seq)
Shape s = A.findLergest(new Seq<Circle>(0));
java
... <T extends GetAreable>
... T findLargest(Seq<? extends T> seq)
ColoredCircle s = A.findLergest(new Seq<Circle>(0));
java
... <S>
... boolean contains(Seq<? extends S> seq, S obj)
A.contains(shapeSeq, "Hello"); // Seq<Shape>, String