title: Generic return type upper bound - interface vs. class - surprisingly valid code
body: <p><em>This is a real-world example from a 3rd party library API, but simplified.</em></p>
  
  <p><em>Compiled with Oracle JDK 8u72</em></p>
  
  <p>Consider these two methods:</p>
  
  <pre><code>&lt;X extends CharSequence&gt; X getCharSequence() {
      return (X) "hello";
  }
  
  &lt;X extends String&gt; X getString() {
      return (X) "hello";
  }
  </code></pre>
  
  <p>Both report an "unchecked cast" warning - I get why. The thing that baffles me is why can I call</p>
  
  <pre><code>Integer x = getCharSequence();
  </code></pre>
  
  <p>and it compiles? The compiler should know that <code>Integer</code> does not implement <code>CharSequence</code>. The call to</p>
  
  <pre><code>Integer y = getString();
  </code></pre>
  
  <p>gives an error (as expected)</p>
  
  <blockquote>
  <pre><code>incompatible types: inference variable X has incompatible upper bounds java.lang.Integer,java.lang.String
  </code></pre>
  </blockquote>
  
  <p>Can someone explain why would this behaviour be considered valid? How would it be useful?</p>
  
  <p>The client does not know that this call is unsafe - the client's code compiles without warning. Why wouldn't the compile warn about that / issue an error?</p>
  
  <p>Also, how is it different from this example:</p>
  
  <pre><code>&lt;X extends CharSequence&gt; void doCharSequence(List&lt;X&gt; l) {
  }
  
  List&lt;CharSequence&gt; chsL = new ArrayList&lt;&gt;();
  doCharSequence(chsL); // compiles
  
  List&lt;Integer&gt; intL = new ArrayList&lt;&gt;();
  doCharSequence(intL); // error
  </code></pre>
  
  <p>Trying to pass <code>List&lt;Integer&gt;</code> gives an error, as expected:</p>
  
  <blockquote>
  <pre><code>method doCharSequence in class generic.GenericTest cannot be applied to given types;
    required: java.util.List&lt;X&gt;
    found: java.util.List&lt;java.lang.Integer&gt;
    reason: inference variable X has incompatible bounds
      equality constraints: java.lang.Integer
      upper bounds: java.lang.CharSequence
  </code></pre>
  </blockquote>
  
  <p>If that is reported as an error, why <code>Integer x = getCharSequence();</code> isn't?</p>