I believe this is because Callable
declares a return type, and Runnable
does not.
From the JLS section 15.12.2.5, the overload with the most specific type is chosen, if there is one unambiguously most specific. This is what it says about most specific functional interface types:
A functional interface type S is more specific than a functional interface type T for an expression e if T is not a subtype of S and one of the following is true (where U1 ... Uk and R1 are the parameter types and return type of the function type of the capture of S, and V1 ... Vk and R2 are the parameter types and return type of the function type of T):
If e is an explicitly typed lambda expression (§15.27.1), then one of the following is true:
- R2 is void...
T
is Runnable
, S
is Callable
, Callable
is more specific because its return type is not void, therefore Callable
is chosen
Method overload resolution is very complicated, so there may be a bit I've missed, but I think this is why it chooses Callable