简单地说,我的问题的关键是学会理解jls。我相信所有jls都是真的。
考虑jls的下一个片段:
8.4.8.1。覆盖(通过实例方法)
在类C中声明的实例方法m1会覆盖另一个实例 方法m2,在A类中声明如果满足以下所有条件:
C是A的子类。
m1的签名是m2签名的子签名(§8.4.2)。
或者:
m2是公共,受保护或声明的默认访问权限 打包为C,或
m1覆盖方法m3(m3与m1不同,m3与m2不同), 这样m3就会覆盖m2。
此外,如果m1不是抽象的,则说m1实现任何和 它覆盖的所有抽象方法声明。
转到子签名声明:
方法m1的签名是a的签名的子签名 方法m2如果:
m2与m1具有相同的签名,或
m1的签名与签名的擦除(§4.6)相同 m2。
关于同一签名:
如果两个方法具有相同的名称,则它们具有相同的签名 参数类型。
哪个规则允许使用协变返回类型?
答案 0 :(得分:4)
这些规则都不允许协变返回类型。方法的签名是指方法名称及其参数的类型和顺序,而不是返回类型。
如果返回类型为R1的方法声明d1覆盖或隐藏了另一个返回类型为R2的方法d2的声明,那么对于d2,d1必须是return-type-substitutable(第8.4.5节),或者是编译时错误发生。
此规则允许协变返回类型 - 在覆盖方法时优化方法的返回类型。
指Section 8.4.5,其中指出:
返回类型为R1的方法声明d1是另一个方法d2的return-type-substitutable,返回类型为R2 iff以下任何一个为真:
如果R1无效,则R2无效。
如果R1是基本类型,则R2与R1相同。
如果R1是引用类型,则以下之一为真:
R1,适应d2(§8.4.4)的类型参数,是R2的子类型。
可以通过未经检查的转换(第5.1.9节)将R1转换为R2的子类型。
d1与d2(§8.4.2)的签名不同,R1 = | R2 |。
(强调我的)
我加粗的部分允许协变返回类型。