Type annotations in static initializers

Jonathan Gibbons jonathan.gibbons at oracle.com
Wed Feb 20 18:59:45 PST 2013

On 02/18/2013 05:23 PM, Werner Dietl wrote:
> Jon, all,
> I just noticed that type annotations in a static initializer block are
> not stored in bytecode.
> Take this example:
> class Test {
>      static {
> 	Object o = new @TA Object();
>      }
> }
> Attr.visitBlock correctly attributes the annotation and in the end
> localEnv.info.scope.owner contains the @TA annotation.
> The owner.toString() gives "Test" and is of kind STATIC_INIT.
> However, in com.sun.tools.javac.jvm.ClassWriter.writeMethod(MethodSymbol)
> I later see a MethodSymbol for "<clinit>()" of kind STATIC_INIT.
> This symbol no longer contains the type annotations and therefore
> nothing gets written to bytecode.
> Can somebody point me to the place where the MethodSymbol from Attr is
> re-written into the MethodSymbol that ends up in the ClassWriter?
> I spent some time looking through the code but didn't find this.
> Maybe type annotations should be copied over whenever one symbol is
> re-written into another one?
> Thanks for any hints!
> cu, WMD.

In general, this sort of work is done in Lower.  However, in this case,
a search on Names.clinit shows nothing there.   But in Gen, you can find 
this code:

         // If there are class initializers, create a <clinit> method
         // that contains them as its body.
         if (clinitCode.length() != 0) {
             MethodSymbol clinit = new MethodSymbol(
                 STATIC | (c.flags() & STRICTFP),
                 new MethodType(
                     List.<Type>nil(), syms.voidType,
                     List.<Type>nil(), syms.methodClass),
             List<JCStatement> clinitStats = clinitCode.toList();
             JCBlock block = make.at(clinitStats.head.pos()).Block(0, 
             block.endpos = TreeInfo.endPos(clinitStats.last());
             methodDefs.append(make.MethodDef(clinit, block));

-- Jon

More information about the type-annotations-dev mailing list