Is a method with receiver parameter override-equivalent to the same method declaration without receiver parameter?

半世苍凉 提交于 2019-12-24 07:08:36

问题


I have a rather technical question concerning the definition of override-equivalent (JLS 8.4.2) in the context of receiver parameters.

Edit: After posting this question, there was a lot of confusion in the comments about receiver parameters. Many people seemed to believe that having a parameter named this in the code below is illegal and therefore misunderstood the question. Please refer to https://docs.oracle.com/javase/specs/jls/se9/html/jls-8.html#jls-8.4.1 if you do not know this feature. A perhaps more easily understandable explanation can be found here: http://blog.joda.org/2015/12/explicit-receiver-parameters.html. This question is very technical and addresses rather experienced Java developers who are familiar with receiver parameters and know the Java Language Specification (JLS) well.

The term override-equivalent is defined as follows:

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.

Two method signatures m1 and m2 are override-equivalent iff either m1 is a subsignature of m2 or m2 is a subsignature of m1.

Thus, if I understand correctly, the two methods in the following class are not override-equivalent, even though, intuitively, I would have expected them to be:

class A {
    void foo(A this) { /* ... */ }
    void foo() { /* ... */ }
}

Nevertheless, obviously I cannot declare both methods in the same class, and when I try to do so, the compiler rightfully complains that foo() is already defined.

My question consists of two parts:

  1. Do I understand correctly that the above two methods are not override-equivalent?
    • If no: What part of the definition did I miss?
    • If yes: What rule in the JLS formally forbids the above two method definitions to be simultaneously present in the same class, since in this case it cannot be the rule "It is a compile-time error to declare two methods with override-equivalent signatures in a class." (JLS 8.4.2)

回答1:


Ok, I found out the answer, and I'll just leave it here in the hopes it may someday help someone.

The answer to my two-part question would be:

  1. No, the two methods in the original post are override-equivalent.

  2. The relevant part of the definition is the first sentence of JLS 8.4.2:

Two methods or constructors, M and N, have the same signature if they have the same name, the same type parameters (if any) (§8.4.4), and, after adapting the formal parameter types of N to the the type parameters of M, the same formal parameter types.

I had read that part, but I assumed that a receiver parameter, while special, is also to be considered as (a special kind of) formal parameter. Thus I assumed that receiver parameters were implicitly included in the sentence "(...) after adapting the formal parameter types (...)" (emphasis mine). However, that is not the case. Receiver parameters are not also formal parameters; rather, the definitions of receiver parameter and formal parameter are mutually exclusive. Therefore, receiver parameters are not part of a method signature as defined in the above quote. Since the definition of override-equivalent uses the definition of a method signature, this also means that the two methods in my original post are in fact override-equivalent (because they do have the same signature!).

The relevant section that clarifies that receiver parameters are indeed not also formal parameters comes slightly later in section JLS 8.4.2:

The receiver parameter is an optional syntactic device for an instance method or an inner class's constructor. For an instance method, the receiver parameter represents the object for which the method is invoked. For an inner class's constructor, the receiver parameter represents the immediately enclosing instance of the newly constructed object. Either way, the receiver parameter exists solely to allow the type of the represented object to be denoted in source code, so that the type may be annotated. The receiver parameter is not a formal parameter; more precisely, it is not a declaration of any kind of variable (§4.12.3), it is never bound to any value passed as an argument in a method invocation expression or qualified class instance creation expression, and it has no effect whatsoever at run time.

(emphasis mine)

The statement that the receiver parameter is not a formal parameter got a bit lost in that big blob of text there.



来源:https://stackoverflow.com/questions/49533897/is-a-method-with-receiver-parameter-override-equivalent-to-the-same-method-decla

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!