是协变量返回类型覆盖根据jls? [英] Is covariant return type overriding according jls?

查看:243
本文介绍了是协变量返回类型覆盖根据jls?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述



我相信所有的jls都是真理。



考虑来自jls的下一个片段:


8.4.8.1。覆盖(通过实例方法)



在类C中声明的实例方法m1覆盖另一个实例
方法m2,在类A中声明iff是真的:



C是A的子类。



m1的签名是一个子签名.2)的签名m2。





m2是公开的,受保护的或声明默认访问与C相同的
包,或



m1覆盖方法m3(m3不同于m1,m3不同于m2),
这样m3重写m2。



此外,如果m1不是抽象的,那么m1被称为实现any和
它覆盖的所有抽象方法的声明。


转到子签名声明:


方法m1的签名是
方法m2的签名的子签名,如果:



m2具有与m1相同的签名,或



m1的签名与m2的签名
的擦除(§4.6)相同。


关于同一签名:


如果两个方法具有相同的名称, $ b参数类型。


哪个规则允许使用协变返回类型?我看不到。



@ rgettman answer



 返回类型为R1的方法声明d1是返回类型可替换的, iff任何以下是真的:
...
- 如果R1是引用类型,则下列之一为真:
---- R1,适用于类型参数的d2(§8.4.4),是R2的一个子类型。
...

和子签名要求:


方法m1的签名是
方法m2的签名的子签名,如果:



m2具有与m1相同的签名,或者



m1的签名与m2的签名
的擦除(§4.6)相同。 p>

对我来说看起来像是矛盾。

解决方案

这些规则都不允许协变返回类型。方法的签名引用方法名称及其参数的类型和顺序,但不引用返回类型。



从JLS,第8.4.8.3节


如果返回类型为R1的方法声明d1覆盖或隐藏了返回类型为R2的另一个方法d2的声明,那么d1必须是return-type-substituteable



此规则允许协变返回类型 - 细化方法的返回类型覆盖它。


这是指第8.4.5节,其中规定:


返回类型为R1的方法声明d1是返回类型可替换的,返回类型为R2的另一个方法d2 iff下列任何一个为真:


$ b


  • 如果R1是原始类型,那么R2是无效的

    b ul>
  • R1,适用于d2的类型参数(§8.4.4),是R2的子类型


  • R1可以通过未经检查的转换(§5.1.9)转换为R2的子类型。


  • 与d2(§8.4.2)相同的签名,以及R1 = | R2 |。




  • (强调我)



    我加粗的部分允许协变返回类型。


    just say, that point of my question is learn to understand jls.

    I believe that all in jls is truth.

    consider next snippet from jls:

    8.4.8.1. Overriding (by Instance Methods)

    An instance method m1, declared in class C, overrides another instance method m2, declared in class A iff all of the following are true:

    C is a subclass of A.

    The signature of m1 is a subsignature (§8.4.2) of the signature of m2.

    Either:

    m2 is public, protected, or declared with default access in the same package as C, or

    m1 overrides a method m3 (m3 distinct from m1, m3 distinct from m2), such that m3 overrides m2.

    Moreover, if m1 is not abstract, then m1 is said to implement any and all declarations of abstract methods that it overrides.

    go to subsignature declaration:

    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

    the signature of m1 is the same as the erasure (§4.6) of the signature of m2.

    about same signature:

    Two methods have the same signature if they have the same name and argument types.

    Which rule does allow to use covariant return type ? I don't see it.

    P.S. after @rgettman answer

    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 a reference type then one of the following is true:
    ----R1, adapted to the type parameters of d2 (§8.4.4), is a subtype of R2.
    ...
    

    and subsignature requirement:

    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

    the signature of m1 is the same as the erasure (§4.6) of the signature of m2.

    For me it is looks like contradiction.

    解决方案

    Neither of these rules allows covariant return types. Signatures of a method refer to the method name and the types and order of its arguments, but not to the return type.

    From JLS, Section 8.4.8.3:

    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.

    That refers to Section 8.4.5, which states:

    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:

      • R1, adapted to the type parameters of d2 (§8.4.4), is a subtype of R2.

      • R1 can be converted to a subtype of R2 by unchecked conversion (§5.1.9).

      • d1 does not have the same signature as d2 (§8.4.2), and R1 = |R2|.

    (emphasis mine)

    That part I bolded allows covariant return types.

    这篇关于是协变量返回类型覆盖根据jls?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆