title: How does Java know which overloaded method to call with lambda expressions? (Supplier, Consumer, Callable, ...)
body: <p>First off, I have no idea how to decently phrase the question, so this is up for suggestions.</p>
  <p>Lets say we have following overloaded methods:</p>
  <pre class="lang-java prettyprint-override"><code>void execute(Callable&lt;Void&gt; callable) {
      try {
          callable.call();
      } catch (Exception e) {
          e.printStackTrace();
      }
  }
  
  &lt;T&gt; T execute(Supplier&lt;T&gt; supplier) {
      return supplier.get();
  }
  
  void execute(Runnable runnable) {
      runnable.run();
  }
  </code></pre>
  <p>Going off from this table, I got from <a href="https://stackoverflow.com/a/62434813/3845362">another SO question</a></p>
  <pre><code>Supplier       ()    -&gt; x
  Consumer       x     -&gt; ()
  BiConsumer     x, y  -&gt; ()
  Callable       ()    -&gt; x throws ex
  Runnable       ()    -&gt; ()
  Function       x     -&gt; y
  BiFunction     x,y   -&gt; z
  Predicate      x     -&gt; boolean
  UnaryOperator  x1    -&gt; x2
  BinaryOperator x1,x2 -&gt; x3
  </code></pre>
  <p>These are the results I get locally:</p>
  <pre class="lang-java prettyprint-override"><code>// Runnable -&gt; expected as this is a plain void  
  execute(() -&gt; System.out.println()); 
  
  // Callable -&gt; why is it not a Supplier? It does not throw any exceptions..
  execute(() -&gt; null);
  
  // Supplier -&gt; this returns an Object, but how is that different from returning null?
  execute(() -&gt; new Object());
  
  // Callable -&gt; because it can throw an exception, right?
  execute(() -&gt; {throw new Exception();});
  </code></pre>
  <p>How does the compiler know which method to call?
  How does it for example make the distinction between what's a <code>Callable</code> and what's a <code>Runnable</code>?</p>