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:
public class ExtraSortList<E> extends ArrayList<E> {
    ExtraSortList(E... elements) {
        super(Arrays.asList(elements));
    }
    public List<E> sortedCopy(Comparator<? super E> c) {
        List<E> sorted = new ArrayList<E>(this);
        Collections.sort(sorted, c);
        return sorted;
    }
    public static void main(String[] args) {
        ExtraSortList<String> stringList = new ExtraSortList<>("foo", "bar");
        Comparator<? super String> 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
    }
}
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)
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.
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 list is typed to <String>, so should the returned List.
Why does Java 8 discard the generic type from the class on the return value?
EDIT: If the method signature of sortedCopy is changed (as pointed out by biziclop) to
public List<E> sortedCopy(Comparator c) {
then the compiler does consider the generic type E from the type ExtraSortList<E> and no error appears. But now the parameter c is a raw type and thus the compiler cannot validate the generic type of the provided Comparator.
EDIT: 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:
- Scope of a Declaration of the generic type Eis the classExtraSortList, this includes the methodsortedCopy.
- The method sortedCopyitself does not declare a generic type variable, it just refers to the type variableEfrom the class scope. see Generic Methods in the JLS
- The JLS also states in the same section 
Type arguments may not need to be provided explicitly when a generic method is invoked, as they can often be inferred (§18 (Type Inference)). 
- The reference stringListis defined withString, thus the compiler does not need to infer a type forEon the invocation ofsortedCopybecause it is already defined.
- Because stringListalready has a reified type forE, the parametercshould beComparator<? super String>for the given invocation.
- The return type should also use the already reified type E, thus it should beList<String>.
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.
 
    