I found in the OpenJDK (11) the implementation of Optional.ifPresent() method. Here it is:
public void ifPresent(Consumer<? super T> action) {
if (this.value != null) {
action.accept(this.value);
}
}
And I can't understand why this particular template is written: <? super T>
For example, we have classes A, B, C:
private static class A {
protected void call() {
System.out.println("Call A");
}
}
private static class B extends A {
@Override
protected void call() {
System.out.println("Call B");
}
}
private static class C extends B {
@Override
protected void call() {
System.out.println("Call C");
}
}
And some calling main method:
public static void main(String[] args) {
final Optional<B> opt = Optional.of(new B());
opt.ifPresent(A::call);
}
I could call my main method with opt.ifPresent(A::call); and with opt.ifPresent(B::call); and can't with opt.ifPresent(C::call);. Ok, I understand that. But why exactly <? super T>? I can achieve the same behavior with <T> template. Can someone help me understand this and give me an example of why this is necessary?
Update:
Finally, I found an example where the <T> type isn't enough in the ifPresent(Consumer<? super T> action) signature.
Example: Let's imagine that the signature of our method is:
public void ifPresent(Consumer<T> action)
In this case we can't use the method that way:
Optional<B> opt = Optional.of(new B());
opt .ifPresent(new Consumer<Object>() {
@Override
public void accept(final Object obj) {
//compiler error: 'java: incompatible types'
}
});
But in the case with:
public void ifPresent(Consumer<? super T> action)
it's possible, and code compiles without any error.