I do not get the difference between:
<V extends SomeInterface> BinaryOperator<V> method() {...}
and:
BinaryOperator<? extends SomeInterface> method() {...}
The whole snippet:
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
class Scratch {
interface SomeInterface {
boolean isEditable();
}
static class One implements SomeInterface {
public String specificMethod() {
return "Hello";
}
@Override
public boolean isEditable() {
return false;
}
}
public static void main(String[] args) {
Stream.of(new One())
.collect(Collectors.toMap(
// cannot resolve method 'specificMethod' in 'SomeInterface' in collector:
key -> key.specificMethod(),
Function.identity(),
chooseNotEditable()
));
}
// works:
// static <V extends SomeInterface> BinaryOperator<V> chooseNotEditable() {
//
// Doesn't work:
// static BinaryOperator<? extends SomeInterface> chooseNotEditable() {
return (current, other) -> current.isEditable() ? current : other;
}
}
I'm doing this because I want to have one generic mergeFunction to many implementations of SomeInterface
. The commented solution works, but I want to understand why the version with the wildcard is not working.
CodePudding user response:
The first (V) is called a generic. This means that you define a method for a certain type. You can reuse this type in several lines of code. The type stays the same. Then the second (?) is called a wildcard. This means that you define a method for an object of which you do not know the type. In further lines of code, you probably will not call specific methods on the object.
Please also read this question.
Kind regards, Marja