title: Java: How does use of Optional.empty() compile?
body: <p>This seems like a really stupid question, but I can't understand <em>why</em> this use of <code>Optional&lt;T&gt;</code> compiles:</p>
  
  <pre><code>import java.util.Optional;
  
  public class Driver {
      static void foo(Optional&lt;String&gt; x) { }
  
      public static void main() {
          foo(Optional.empty());
      }
  }
  </code></pre>
  
  <p><a href="http://docs.oracle.com/javase/8/docs/api/java/util/Optional.html#empty--" rel="noreferrer"><code>Optional::empty</code></a> is defined as returning me an <code>Optional&lt;T&gt;</code>. Inside of <code>Driver::main</code>, the expression <code>Optional.empty()</code> seems like it would return an <code>Optional&lt;Object&gt;</code>, as I am not parameterizing the use of <code>Optional</code> so I would expect it to fall back to <code>Object</code> as the type parameter. Then, I'm passing the <code>Optional&lt;Object&gt;</code> to a function which expects an <code>Optional&lt;String&gt;</code>, which is a downcast of the parameter, which should not be allowed. I would expect to see something like:</p>
  
  <pre><code>incompatible types: Optional&lt;Object&gt; cannot be converted to Optional&lt;String&gt;
  </code></pre>
  
  <p>However, the code compiles perfectly fine. Clearly, my thought process here is incorrect...but where?</p>
  
  <hr>
  
  <p>Let me clarify what I'm looking for in an answer here...I know what type inference is. What I don't understand <em>how</em> it is happening here and what changed in the language from Java 7 to Java 8. For example, this bit of code compiles perfectly fine in Java 8, but fails in Java 7:</p>
  
  <pre><code>final class Opt&lt;T&gt; {
      private final T value;
  
      Opt(T x) {
          value = x;
      }
  
      public static &lt;T&gt; Opt&lt;T&gt; empty() {
          return new Opt&lt;T&gt;(null);
      }
  }
  
  public class Driver {
      static void bar(Opt&lt;String&gt; x) { }
  
      public static void main() {
          bar(Opt.empty());
      }
  }
  </code></pre>
  
  <p>How does this work in Java 8 when you have to deal with things like overloading? Is there a specific section of the Java language specification that talks about this sort of thing?</p>