Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why java compiler doesn't discriminate methods with different types?

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?

like image 895
Jin Kwon Avatar asked Jun 28 '26 14:06

Jin Kwon


1 Answers

This is because collection::add is not pertinent to applicability when invoking doSome(T).

Specifically, it is this case:

If m is a generic method and the method invocation does not provide explicit type arguments, an explicitly typed lambda expression or an exact method reference expression for which the corresponding target type (as derived from the signature of m) is a type parameter of m.

m here is doSome, which is a generic method. collection:add is an exact method reference. Its target type is (T) -> boolean (a function that takes in a T and returns boolean). (T) -> boolean includes the type parameter T, 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::add is practically "ignored", doSome(T) is also an applicable method, in addition to doSome(Consumer), which is obviously applicable. Therefore, there is an overload resolution ambiguity.

I would just add a cast to fix this:

doSome((Consumer<? super Other>)collection::add);

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.

like image 80
Sweeper Avatar answered Jun 30 '26 04:06

Sweeper



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!