为什么此协变 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).
为什么以下代码不产生编译时未经检查的警告:
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 typeC<F1,...,Fn>
are all of the following:
- The direct superclass of
C<F1,...,Fn>
.- The direct superinterfaces of
C<F1,...,Fn>
.- The type
Object
, ifC<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 thenewdefinition ofStringSorter
because the return type ofOverrider.toList
isList
, 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).