为什么此协变 return 类型声明不会产生未处理的警告?

Why this covariant return type declaration doesn't produce an unckecked warning?

为什么以下代码不产生编译时未经检查的警告:

class Parent {
    public List method(){
        return null;
    }
}

class Child extends Parent {

    public List<String> method() {
        return null;
    }
}

而以下实际上是:

class Parent {
    public List<String> method(){
        return null;
    }
}

class Child extends Parent {

    public List method() {
        return null;
    }
}

我实际上是在 JLS 中寻找此行为的参考。

因为 List 不是 List<String> 的子类型但是(如您所知)List<String> [=12= 的子类型].

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();
    } 
}

这表示您的第一个示例,其中子项中的 return 类型是父项的子类型。同样,在您的示例中,List<String>List.

的子类型

4.10.2. Subtyping among Class and Interface Types

Given a generic type declaration C<F1,...,Fn> (n > 0), the direct supertypes of the generic type C<F1,...,Fn> are all of the following:

  • The direct superclass of C<F1,...,Fn>.
  • The direct superinterfaces of C<F1,...,Fn>.
  • The type Object, if C<F1,...,Fn> is a generic interface type with no direct superinterfaces.
  • The raw type C. (boldness mine)

同时:

class StringSorter {
    // turns a collection of strings into a sorted list
    List<String> toList(Collection<String> c) {...}
}
class Overrider extends StringSorter {
    List toList(Collection c) {...}
}

是您的第二个代码段的示例。

An unchecked warning would be given when compiling Overrider against the new definition of StringSorter because the return type of Overrider.toList is List, which is not a subtype of the return type of the overridden method, List<String>. (striking mine)

JLS examples 8.4.8.3-1 & 8.4.8.3-2 特别是:

8.4.8.3. Requirements in Overriding and Hiding

If a method declaration d1 with return type R1 overrides or hides the declaration of another method d2 with return type R2, then d1 must be return-type-substitutable (§8.4.5) for d2, or a compile-time error occurs.

This rule allows for covariant return types - refining the return type of a method when overriding it.

If R1 is not a subtype of R2, a compile-time unchecked warning occurs unless suppressed by the SuppressWarnings annotation (§9.6.4.5).