toUpperCase
has an overload that takes no parameters, and another overload that takes one parameter (Locale
).
This makes the expression String::toUpperCase
an inexact method reference expression. The expression could either refer to the no-argument overload, or the one-argument overload.
Both of the two fun
s are determined to be "potentially applicable", specifically because of this clause:
A method reference expression is potentially compatible with a functional interface type T
if, where the arity of the
function type of T
is n, there exists at least one potentially
applicable method when the method reference expression targets the
function type with arity n, and one of the following is true:
- The method reference expression has the form
ReferenceType :: [TypeArguments] Identifier
and at least one potentially applicable
method is either (i) static and supports arity n, or (ii) not static
and supports arity n-1.
- [irrelevant]
String::toUpperCase
is potentially compatible with Function<String, String>
, because Function<String, String>
has arity 1 (takes one parameter), and toUpperCase
is non-static and has a no-argument overload.
String::toUpperCase
is potentially compatible with Comparator<String>
, because Comparator<String>
has arity 2, and toUpperCase
is non-static and has a one-argument overload. Note that this step does not check the parameter types or return types at all. It doesn't matter that the parameter type is Locale
but String
is actually expected.
After finding the potentially applicable methods, we go on to Identify Matching Arity Methods Applicable by Strict Invocation. This is where things go wrong. Remember how String::toUpperCase
is an inexact method reference? That means it's not pertinent to applicability - the compiler doesn't consider the method reference at all during this step. See also this other question that also involves an inexact method reference expression causing overload resolution errors.
So both fun
s are applicable by strict invocation. The next step is to find the most specific method. This step considers subtyping, like String
is more specific than Object
. But Comparator<String>
is unrelated to Function<String, String>
, so we cannot find the most specific method, and an error occurs.