Interesting inference case

Dan Smith daniel.smith at
Tue Sep 10 15:07:52 PDT 2013

See the "Overload resolution simplification" thread.

this::call is an inexact method reference when 'call' is overloaded, and exact otherwise.

Inexact method references are ignored (we don't try to resolve them, or figure out their return type, etc.) until the outer overload resolution is done.  Hence, there's no basis for choosing one variant of 'submit' over another.

Exact method references can influence overload resolution.  In this case, because 'call' returns 'void', we know that the method reference cannot be a Callable, and so that candidate is discarded.


On Sep 2, 2013, at 11:19 AM, Sam Pullara <spullara at> wrote:

> I was trying to pass Semaphore::release to ExecutorService.submit and ran into a puzzling compile error. Here is a reproduction case:
> public class InferTest {
>    void call() {}
> //    void call(int i) {}
>    @Test
>    public void test() {
>        ExecutorService es = Executors.newCachedThreadPool();
>        es.submit(this::call);
>    }
> }
> With the comment, this compiles fine. If you uncomment the second call() method it fails with:
> java: reference to submit is ambiguous
>  both method <T>submit(java.util.concurrent.Callable<T>) in java.util.concurrent.ExecutorService and method submit(java.lang.Runnable) in java.util.concurrent.ExecutorService match
> java: incompatible types: cannot infer type-variable(s) T
>    (argument mismatch; bad return type in method reference
>      void cannot be converted to T)
> I'm not sure why the overload on call() would cause the ambiguity. 
> Sam

More information about the lambda-libs-spec-observers mailing list