I defined following methods.
class Some {
void doSome(Consumer<? super Other> consumer) {
}
<T extends Collection<? super Other>> T doSome(T collection) {
doSome(collection::add); // <<<<<<<<<<<<<<<<<<<
return collection;
}
}
Now the javac complains.
java: reference to getAttributes is ambiguous both method doSome(java.util.function.Consumer<? super Other>) in ... and method doSome(T) in ...Some match
Why javac couldn't discriminate Consumer and Collection?
This is because
collection::addis not pertinent to applicability when invokingdoSome(T).Specifically, it is this case:
mhere isdoSome, which is a generic method.collection:addis an exact method reference. Its target type is(T) -> boolean(a function that takes in aTand returnsboolean).(T) -> booleanincludes the type parameterT, so it is not pertinent to applicability."Pertinent to applicability" is Java's way of deciding what argument expressions to consider during overload resolution. It simply doesn't consider some arguments (those that are not pertinent to applicability), because that would make overload resolution too complicated.
Since
collection::addis practically "ignored",doSome(T)is also an applicable method, in addition todoSome(Consumer), which is obviously applicable. Therefore, there is an overload resolution ambiguity.I would just add a cast to fix this:
A cast expression is pertinent to applicability.
See also this similar question which is about implicitly typed lambda expressions, which are also not pertinent to applicability.