enhanced-metadata-spec-discuss Digest, Vol 12, Issue 4

Srikanth S Adayapalam srikanth_sankaran at in.ibm.com
Mon Aug 26 11:56:28 PDT 2013


Hello !

I am trying to understand certain scenarios where javac 8b100 seems to 
deviate
from the spec.

(1) For the following case: 

// --
public class X {
    void foo() {
        class Local {
        }
    }
}
// --

why would javac emit a mandated formal parameter as in

 X$1Local(X);
   descriptor: (LX;)V
   flags:
   Code:
     stack=2, locals=2, args_size=2
        0: aload_0
        1: aload_1
        2: putfield      #1                  // Field this$0:LX;
        5: aload_0
        6: invokespecial #2                  // Method 
java/lang/Object."<init>
:()V
        9: return
     LineNumberTable:
       line 3: 0
   MethodParameters:
     Name                           Flags
     this$0                         final mandated

// --

I would think this is covered by "The local/
anonymous class is necessarily emitted by the same compiler as the class 
instance creation
expression. That compiler can represent the immediately enclosing instance 
how ever
it wishes. There is no need for the Java programming language to 
implicitly declare a
parameter in the local/anonymous class's constructor."

and so the parameter need not be mandated ?

However, per 13.1 we have:

A construct emitted by a Java compiler must be marked as mandated if it
corresponds to a formal parameter declared implicitly in source code 
(§8.8.9,
§8.9.2, §15.9.5.1) and per a reading of 15.9.5.1. seems to imply that 
this$0 above should be mandated, since class Local is not 
occurring in a static context. 


(2) 8.8.9 point 3) reads:

 In a class instance creation expression for an anonymous class, and where 
the anonymous
class's superclass is inner, §15.9.2 specifies the immediately enclosing 
instance with respect
to the superclass. Similar to (1), the superclass may have been emitted by 
a compiler which
is different than the compiler of the class instance creation expression. 
Therefore, there
must be a standard way for the compiler of the creation expression to pass 
a reference
(representing the immediately enclosing instance with respect to the 
superclass) to the
superclass's constructor. Consequently, the Java programming language 
deems that an
anonymous class's constructor implicitly declares an initial parameter for 
the immediately
enclosing instance with respect to the superclass.


8b100's behavior is confusing on the following code:

// --
public class X {
    void foo() {
        new Y().new Z() {
        };
    }
}
class Y {
    class Z {}
}
// --

  final X this$0;
    descriptor: LX;
    flags: ACC_FINAL, ACC_SYNTHETIC

  X$1(X, Y);
    descriptor: (LX;LY;)V
    flags:
    Code:
      stack=3, locals=3, args_size=3
         0: aload_0
         1: aload_1
         2: putfield      #1                  // Field this$0:LX;
         5: aload_0
         6: aload_2
         7: dup
         8: invokevirtual #2                  // Method 
java/lang/Object.getClas
s:()Ljava/lang/Class;
        11: pop
        12: invokespecial #3                  // Method 
Y$Z."<init>":(LY;)V
        15: return
      LineNumberTable:
        line 3: 0
    MethodParameters:
      Name                           Flags
      this$0                         final mandated
      x0

Why would the anonymous class's own enclosing instances be mandated
while "x0" which I presume is the super classes enclosing instance
be flag less ? 

Thanks in advance for any explanations.
Srikanth.


More information about the enhanced-metadata-spec-discuss mailing list