Java annotations - javac compiler bug?
annotations, java, javac, nested-class
Solution
This is a javac compiler bug, see: https://bugs.openjdk.java.net/browse/JDK-8065132 that I just filed.
Problem
I came across a strange effect in connection with annotations on method parameters in a nested class. Looks very much like a compiler issue to me. See below for details and steps to reproduce. Compile the following class with javac (I used javac 1.7.0_51). Note the annotated parameter "boolean param3". ``` import java.lang.annotation.Annotation; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; public class TestAnnotations { public String a; @Retention(RetentionPolicy.CLASS) @interface MyAnnotation {} protected class TestInner { public TestInner(String param1, Object param2, @MyAnnotation boolean param3) {} public void accessField() { System.out.println(TestAnnotations.this.a); } } } ``` Then examine the nested class with javap (i.e. javap -p -v -c TestAnnotations$TestInner.class). Its constructor looks as follows. ``` public test.TestAnnotations$TestInner(test.TestAnnotations, java.lang.String, java.lang.Object, boolean); flags: ACC_PUBLIC Code: stack=2, locals=5, args_size=5 0: aload_0 1: aload_1 2: putfield #1 // Field this$0:Ltest/TestAnnotations; 5: aload_0 6: invokespecial #2 // Method java/lang/Object."<init>":()V 9: return LineNumberTable: line 16: 0 RuntimeInvisibleParameterAnnotations: 0: 1: 2: 0: #18() ``` Note the number of annotations in the attribute RuntimeInvisibleParameterAnnotations - it's 3. At the same time we now observe 4 method parameters because of one additional test.TestAnnotations at the beginning (it is used to pass a reference to TestAnnotations.this into the inner class). This means, @MyAnnotation is now refering to Object param2, shifted by 1 to the left. According to the Virtual Machine Specification the number of annotations should be the same as the number of method parameters: num_parameters The value of the num_parameters item gives the number of parameters of the method represented by the method_info structure on which the annotation occurs. (This duplicates information that could be extracted from the method descriptor (§4.3.3).) Here we clearly see a violation. Does anyone know the reason? Is it really what it seems to be, just a compiler bug?