Java 8 type inference cause to omit generic type on invocation <p>I have a Problem with a generic method after upgrading to Java 1.8, which was fine with Java 1.6 and 1.7 Consider the following code: </p> <pre><code>public class ExtraSortList&lt;E&gt; extends ArrayList&lt;E&gt; { ExtraSortList(E... elements) { super(Arrays.asList(elements)); } public List&lt;E&gt; sortedCopy(Comparator&lt;? super E&gt; c) { List&lt;E&gt; sorted = new ArrayList&lt;E&gt;(this); Collections.sort(sorted, c); return sorted; } public static void main(String[] args) { ExtraSortList&lt;String&gt; stringList = new ExtraSortList&lt;&gt;("foo", "bar"); Comparator&lt;? super String&gt; compGen = null; String firstGen = stringList.sortedCopy(compGen).get(0); // works fine Comparator compRaw = null; String firstRaw = stringList.sortedCopy(compRaw).get(0); // compiler ERROR: Type mismatch: cannot convert from Object to String } } </code></pre> <p>I tried this with the Oracle javac (1.8.0_92) and with Eclipse JDT (4.6.1) compiler. It is the same result for both. (the error message is a bit different, but essentially the same)</p> <p>Beside the fact, that it is possible to prevent the error by avoiding raw types, it puzzles me, because i don't understand the reason.</p> <p>Why does the raw method parameter of the sortedCopy-Method have any effect on the generic type of the return value? The generic type is already defined at class level. The method does not define a seperate generic type. The reference <code>list</code> is typed to <code>&lt;String&gt;</code>, so should the returned List.</p> <p>Why does Java 8 discard the generic type from the class on the return value?</p> <p><strong>EDIT:</strong> If the method signature of sortedCopy is changed (as pointed out by biziclop) to</p> <pre><code>public List&lt;E&gt; sortedCopy(Comparator c) { </code></pre> <p>then the compiler does consider the generic type <code>E</code> from the type <code>ExtraSortList&lt;E&gt;</code> and no error appears. But now the parameter <code>c</code> is a raw type and thus the compiler cannot validate the generic type of the provided Comparator.</p> <p><strong>EDIT:</strong> I did some review of the Java Language Specification and now i think about, whether i have a lack of understanding or this is a flaw in the compiler. Because:</p> <ul> <li><a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.3" rel="nofollow noreferrer" title="Scope of a Declaration">Scope of a Declaration</a> of the generic type <code>E</code> is the class <code>ExtraSortList</code>, this includes the method <code>sortedCopy</code>.</li> <li>The method <code>sortedCopy</code> itself does <em>not declare</em> a generic type variable, it just refers to the type variable <code>E</code> from the class scope. see <a href="https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.4" rel="nofollow noreferrer" title="Generic Methods">Generic Methods</a> in the JLS</li> <li>The JLS also states in the same section <blockquote> <p>Type arguments may not need to be provided explicitly when a generic method is invoked, as they can often be inferred (§18 (Type Inference)).</p> </blockquote></li> <li>The reference <code>stringList</code> is defined with <code>String</code>, thus the compiler does not need to infer a type for<code>E</code> on the invocation of <code>sortedCopy</code> because it is already defined.</li> <li>Because <code>stringList</code> already has a reified type for <code>E</code>, the parameter <code>c</code> should be <code>Comparator&lt;? super String&gt;</code> for the given invocation.</li> <li>The return type should also use the already reified type <code>E</code>, thus it should be <code>List&lt;String&gt;</code>.</li> </ul> <p>This is my current understanding of how i think the Java compiler should evaluate the invocation. If i am wrong, an explanation why my assumptions are wrong would be nice.</p>