Number of formal parameters of anonymous class constructor

Alex Buckley alex.buckley at oracle.com
Mon Aug 3 18:33:16 UTC 2015


On 8/3/2015 5:47 AM, konstantin barzilovich wrote:
> In chapter 15.9.5.1 in JLS signature of anonymous constructor is described.
> In case S is inner non-static class (see the minimal example)
>
> classOuter {
>      publicOuter() {}
>      classA  {
>          publicA() {}
>      }
>      public voidfoo(){
>          A a =newOuter().newA(){};
>      }
> }
>
> we expect to have one formal parameter of type Outer according to
> jls-15.9.5.1-100-B and jls-15.9.5.1-100-B.1.

Let's look at what we have. 'S' is the class A, and with i as the newly 
created instance of the anonymous class:

a) The immediately enclosing instance of i is the instance of Outer on 
which foo() was called.
b) The immediately enclosing instance of i-with-respect-to-A is the 
instance of Outer produced by "new Outer()".

In 15.9.5.1, the JLS prescribes the form of the anonymous class ctor 
(note the phrase "implicitly declared"). In particular, the JLS 
prescribes that (b) is encoded as the first formal parameter of the 
ctor. I guess you could call it the "receiver parameter" but I won't.

You can see the encoding of (b) via reflection. Compile Outer.java with 
javac -parameters, then reflect over the anonymous class to get its 
java.lang.reflect.Constructor, then call getParameters(). Element 0 
should return true for isImplicit().

> But I try to get parameters of constructor via reflection and it has two
> parameters both of type Outer.
> I guess, the second one is a receiver parameter, but it isn't mentioned
> in jls-15.9.5.1-100-B.1.
> Could you please clarify this situation?

The JLS does not prescribe the encoding of (a) into the ctor. It is 
likely that javac is storing (a) as the second parameter, but that's an 
implementation detail which javac is free to change. I guess you could 
call it the "environment parameter" but I won't. Point is, JLS 15.9.5.1 
does not prohibit the existence of the second parameter.

If you reflect with getParameters(), element 1 should return false for 
isImplicit() and true for isSynthetic().

Alex


More information about the compiler-dev mailing list