Java SE 7 规范的 8.4.9 中关于重载的措辞令人困惑
Confusing wording on overloading in 8.4.9 of Java SE 7 Specifications
这里引用JavaSE 7 Specifications的8.4.9第一行:
If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded.
因此,任何不符合覆盖等效条件的都被称为重载。
但是下面示例中的两个方法既不是重写等效的,也不能被视为对重载有效。
public String my_method(int x) {.....}
public int my_method(int x) {.....}
覆盖无效,因为一个的 return 类型不是另一个 return 的子类。
重载无效,因为不同的 return 类型本身不足以将两种方法视为重载。
对 8.4.9 有什么意见吗?可能是我的认知漏掉了什么。
您缺少的是方法的 return 类型不是其签名的一部分。
8.4.2中override-equivalent的定义说:
"Two methods have the same signature if they have the same name and argument types."
请注意,定义中没有提及 return 类型。
然后它说:
The signature of a method m1 is a subsignature of the signature of a method m2 if either:
- m2 has the same signature as m1, or [...]
Two method signatures m1 and m2 are override-equivalent iff either m1 is a subsignature of m2 or m2 is a subsignature of m1.
因此两个名称和参数类型相同但结果类型不同的方法是覆盖等效的。
最后 8.4.2 说:
"It is a compile-time error to declare two methods with override-equivalent signatures in a class."
所以如果方法在同一个 class.
中,则您的示例代码是非法的
另一方面,如果一个在包含另一个的class的子class中,那么根据8.4.5中的规则,这两种方法都不是return-type-substitutable 与其他......所以这也将是一个编译错误。
来自其他两个部分的以下信息解决了您的问题:
It is a compile-time error to declare two methods with override-equivalent signatures in a class.
A method declaration d1 with return type R1 is return-type-substitutable for another method d2 with return type R2, if and only if the following conditions hold:
If R1 is void then R2 is void.
If R1 is a primitive type, then R2 is identical to R1.
If R1 is a reference type then:
R1 is either a subtype of R2 or R1 can be converted to a subtype of R2 by unchecked conversion (§5.1.9), or
R1 = |R2|
根据8.4.2. Method Signature the return type is not part of the signature. So the methods in your question are not overloads, but they are overrides. This override is not compatible due to an incompatible change to the method result, as specified in 8.4.5. Method Result:
Return types may vary among methods that override each other if the return types are reference types. The notion of return-type-substitutability supports covariant returns, that is, the specialization of the return type to a subtype.
A method declaration d1
with return type R1
is return-type-substitutable for another method d2
with return type R2
iff any of the following is true:
- If
R1
is void
then R2
is void
.
- If
R1
is a primitive type then R2
is identical to R1
.
- If
R1
is a reference type then one of the following is true:
这在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.
这里引用JavaSE 7 Specifications的8.4.9第一行:
If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded.
因此,任何不符合覆盖等效条件的都被称为重载。
但是下面示例中的两个方法既不是重写等效的,也不能被视为对重载有效。
public String my_method(int x) {.....}
public int my_method(int x) {.....}
覆盖无效,因为一个的 return 类型不是另一个 return 的子类。
重载无效,因为不同的 return 类型本身不足以将两种方法视为重载。
对 8.4.9 有什么意见吗?可能是我的认知漏掉了什么。
您缺少的是方法的 return 类型不是其签名的一部分。
8.4.2中override-equivalent的定义说:
"Two methods have the same signature if they have the same name and argument types."
请注意,定义中没有提及 return 类型。
然后它说:
The signature of a method m1 is a subsignature of the signature of a method m2 if either:
- m2 has the same signature as m1, or [...]
Two method signatures m1 and m2 are override-equivalent iff either m1 is a subsignature of m2 or m2 is a subsignature of m1.
因此两个名称和参数类型相同但结果类型不同的方法是覆盖等效的。
最后 8.4.2 说:
"It is a compile-time error to declare two methods with override-equivalent signatures in a class."
所以如果方法在同一个 class.
中,则您的示例代码是非法的另一方面,如果一个在包含另一个的class的子class中,那么根据8.4.5中的规则,这两种方法都不是return-type-substitutable 与其他......所以这也将是一个编译错误。
来自其他两个部分的以下信息解决了您的问题:
It is a compile-time error to declare two methods with override-equivalent signatures in a class.
A method declaration d1 with return type R1 is return-type-substitutable for another method d2 with return type R2, if and only if the following conditions hold:
If R1 is void then R2 is void.
If R1 is a primitive type, then R2 is identical to R1.
If R1 is a reference type then:
R1 is either a subtype of R2 or R1 can be converted to a subtype of R2 by unchecked conversion (§5.1.9), or
R1 = |R2|
根据8.4.2. Method Signature the return type is not part of the signature. So the methods in your question are not overloads, but they are overrides. This override is not compatible due to an incompatible change to the method result, as specified in 8.4.5. Method Result:
Return types may vary among methods that override each other if the return types are reference types. The notion of return-type-substitutability supports covariant returns, that is, the specialization of the return type to a subtype.
A method declaration
d1
with return typeR1
is return-type-substitutable for another methodd2
with return typeR2
iff any of the following is true:
- If
R1
isvoid
thenR2
isvoid
.- If
R1
is a primitive type thenR2
is identical toR1
.- If
R1
is a reference type then one of the following is true:
这在8.4.8.3. Requirements in Overriding and Hiding中也有规定:
If a method declaration
d1
with return typeR1
overrides or hides the declaration of another methodd2
with return typeR2
, thend1
must be return-type-substitutable (§8.4.5) ford2
, or a compile-time error occurs.