Can someone give me an example on what cannot be achieved when the parameter look like this
Function<T, U> keyExtractor?
Given the following classes and interfaces to illustrate the example:
interface Vehicle { Engine getEngine(); }
class Car implements Vehicle { public Engine getEngine(){ return new CombustionEngine(); } }
abstract class Engine implements Comparable<Engine> {
int power; public int compareTo(Engine o){ return Integer.compare(power, o.power); }
}
class CombustionEngine extends Engine {}
? super T would be just T ?Suppose I have a keyExtractor function implemented for Vehicle and I need a Comparator for Car.
Function<Vehicle, Engine> extractor = v -> v.getEngine();
Comparator<Car> comparator = comparing(extractor);
here T must be inferenced as Car since we want a Comparator<Car> but we passed a Function<Vehicle, Engine> to comparing and since Car != Vehicle the code will not compile giving the following error:
error: incompatible types: inference variable T has incompatible equality constraints Car,Vehicle
having Function<? super T, ? extends U> keyExtractor solves this issue since Vehicle is a superclass of Car so the compiler is happy with that.
? extends U would be just U ?Suppose we write our generic types explicitly when calling comparing (e.g. for code convention purposes):
Function<Vehicle, CombustionEngine> combustionExtractor = v -> (CombustionEngine)v.getEngine();
Comparator.<Car, Engine>comparing(combustionExtractor);
here we are explicitly stating that U must be inferenced as Engine but we passed a Function<Vehicle, CombustionEngine> to comparing and since Engine != CombustionEngine the code will not compile giving the following error:
error: incompatible types: Function<Vehicle,CombustionEngine> cannot be converted to Function<? super Car,Engine>
having Function<? super T, ? extends U> keyExtractor solves this issue since CombustionEngine is a subclass of Engine so the compiler is happy with that.