Desugaring of anonymous classes

Alex Buckley alex.buckley at oracle.com
Mon Aug 5 17:00:12 PDT 2013


Mike, Srikanth,

Returning to this topic, there are two scenarios where I would like your 
comments:

1. Type annotation in 'new' expression for anonymous class

Consider this code:

   @Retention(RetentionPolicy.RUNTIME)
   @Target(ElementType.TYPE_USE)
   @interface X {}

   class C { void m() { new @X Foo() {}; } }

The @X annotation is stored as a target_type=CLASS_EXTENDS structure in 
the RuntimeVisibleTypeAnnotations attribute of Foo$1.class. That's fine.

The @X annotation is not stored as a target_type=NEW structure in the 
RuntimeVisibleTypeAnnotations attribute of m's method_info in C.class. 
That's an oversight by javac, especially since the first mail in this 
thread said javac copied type annotations "to the class declaration and 
to its instantiation (new expression)".

2. Declaration annotation for anonymous class in 'new' expression

Take the code above and change the annotation type's target to be TYPE:

   @Retention(RetentionPolicy.RUNTIME)
   @Target(ElementType.TYPE)
   @interface X {}

   class C { void m() { new @X Foo() {}; } }

The @X annotation is stored in the RuntimeVisibleAnnotations structure 
of Foo$1.class. This is a neat trick, since anonymous class declarations 
could not be annotated in SE 7, but it is irregular because annotations 
on declarations traditionally appear as modifiers. If a 'new' expression 
is to provide a declaration context (for TYPE annotations) as well as a 
type context (for TYPE_USE annotations), then the spec needs to spell it 
out.

What's more, annotations on anonymous class declarations could have 
implications for core reflection and other language features. It appears 
that "new @X @X Foo() {};" works at compile-time, but I have not tried 
reflecting over Foo$1.class's RuntimeVisibleAnnotations attribute.

Alex

On 4/1/2013 12:59 PM, Alex Buckley wrote:
> On 3/31/2013 11:39 AM, Michael Ernst wrote:
>> In January, I removed the text from the specification that was
>> compiler-specific.  This text was among the removed text:
>>
>>    As another example, an anonymous class desugars into a class
>> declaration
>>    and instantiation.  A programmer may write both type and declaration
>>    annotations on an anonymous class in Java source code.  In the
>> classfile,
>>    the type annotations are copied to the class declaration and to its
>>    instantiation (new expression).  The declaration annotations are
>> copied
>>    only to the class declaration.
>>
>> Do you consider this possibly implementation-specific, and therefore it
>> does not belong in the specification.  Or, will every compiler follow
>> this
>> implementation strategy so it is worth re-instating as useful guidance?
>
> It would be better to start with the concept of a class instance
> creation expression (CICE) since it lets the locations be more precise.
>
> A CICE may create an instance of an anonymous class, in which case the
> declaration of the anonymous class is provided inline. This declaration
> is required by JLS 13.1 to compile to a form with a binary name; you can
> take this to mean a standalone class file is emitted.
>
> A CICE may have i) type annotations in the 'new ... {' term outside the
> anonymous class declaration, and ii) type annotations and declaration
> annotations inside the anonymous class declaration. It would be
> appropriate to specify:
>
> - The (i) annotations (type only) are stored for the CICE in its
> enclosing class file _and_ stored for the superclass of the anonymous
> class declaration in its emitted class file.
>
> - The (ii) annotations (type and decl) are stored for the appropriate
> type uses and declarations in the class file emitted for the anonymous
> class declaration.
>
> Alex


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