Because it is Listnot a subtype List<String>, but (as you know) List<String>is a subtype List.
Examples given in JLS:
class C implements Cloneable {
C copy() throws CloneNotSupportedException {
return (C)clone();
}
}
class D extends C implements Cloneable {
D copy() throws CloneNotSupportedException {
return (D)clone();
}
}
This is your first example in which the return type of the child is a subtype of the parent. Similarly, in your example List<String>is a subtype List.
4.10.2. Subtyping between classes and interface types
C<F1,...,Fn> (n > 0), C<F1,...,Fn> - :
C<F1,...,Fn>.C<F1,...,Fn>.Object, C<F1,...,Fn> - .C. ( )
:
class StringSorter {
List<String> toList(Collection<String> c) {...}
}
class Overrider extends StringSorter {
List toList(Collection c) {...}
}
.
Overrider StringSorter, Overrider.toList List, , List<String>. ( )
JLS 8.4.8.3-1 8.4.8.3-2 :
8.4.8.3.
d1 R1 d2 R2, d1 return-type-substitutable (§8.4.5) d2 .
- .
R1 R2, SuppressWarnings (§9.6.4.5).