[type-annos-observers] Clarifying the receiver parameter (qualified 'this')

Markus Keller markus_keller at ch.ibm.com
Thu Oct 24 05:56:15 PDT 2013


Michael Ernst <mernst at cs.washington.edu> wrote on 2013-10-23 23:34:10:

> First, the change from
>       [Identifier .] this
> to
>       {Identifier .} this
> was essential.  The reason is that inside a doubly-nested inner class, 
the 
> receiver can have a name like Outer.Middle.this.

Nope, Middle.this is always equivalent to Outer.Middle.this, so the 
"Outer." is never necessary.

Example:

package p;
class Outer {
    class Middle {
        void m() {}
        class Inner {
            @I Inner(pack. at O Outer. at M Middle Middle.this, Middle m) {
                m.m();
                Middle.this.m();
            }
        }
    }
}
class Middle { // nasty, but legal
    void foo() {}
}

The annotations are on the receiver parameter's type, not on its name, so 
the 'this' doesn't have to be qualified with more than the immediately 
enclosing class. By the scoping rules, the name of an enclosing member 
type can always be referenced with a simple name.

I don't buy the argument that allowing a fully-qualified 'this' makes the 
spec simpler. On the contrary: The "8.4.1 Formal Parameters" section in 
308.pdf is full of little errors:

"The receiver parameter of an instance method or inner class constructor 
is an optional syntactic device to represent the object for which the 
method or constructor is invoked."
=> For inner class constructors, the receiver parameter represents the 
immediately enclosing instance of the constructed object, not the object 
for which the constructor is invoked.

"The name of the receiver parameter must either be 'this', or the text of 
a qualified 'this' expression (15.8.3) which would, if present in the body 
of the method or constructor, denote the class of the method or 
constructor's receiver; otherwise, a compile-time error occurs."
=> The "either ... or" doesn't make it clear that an unqualified 'this' 
cannot be used as the receiver parameter of an inner class constructor.

"The type of the receiver parameter must be the class or interface in 
which the method or constructor is declared; otherwise, a compile-time 
error occurs."
=> For an inner class constructor, the type of the receiver parameter is 
_not_ the declaring type of the constructor (which would be the inner 
class), but it's the immediately enclosing class of the inner class.

The Java language should stay as simple as possible. Here, the 
unrestricted qualifications even confused the spec authors. The 
straightforward approach with two separate cases for instance methods and 
for inner class constructors is much easier to handle. Why add code to 
check whether a qualified 'this' is legal when you can just exclude it in 
the grammar? The fully-qualified 'this' adds more complexity to the 
language, not less.


Alex Buckley <alex.buckley at oracle.com> wrote on 2013-10-23 20:27:25:
> The receiver parameter is _not_ "closer to being a declaration", 

The receiver parameter indeed doesn't declare a variable, but it's an 
explicit declaration for the otherwise implicitly declared "this" or 
"Outer.this" object. The declaration declares the annotated type of the 
'this' object. Another similar example is a public no-args constructor 
declaration, which makes the implicit default constructor explicit. 
References can use a fully-qualified type name, but the declaration just 
uses the simple name.

Markus



More information about the type-annotations-spec-observers mailing list