Search code examples
javaannotationsannotation-processing

Representation of inner source-retained annotation


We have this class:

public class MyClass {
    @Retention(RetentionPolicy.SOURCE)
    private @interface MyInterface { }

    @MyInterface
    public void hello() { }
}

As you can see, it has an inner, source-only annotation. My question is: should the exported binary (jar) contain the MyClass$MyInterface.class file or not? If we look at the retention, we can say not, because this annotation should be discarded by the compiler. However it is still added to the list of inner classes in MyClass.class, and the MyClass$MyInterface.class file is also created.

When we run an an annotation processor against this class

public class MyProcessedClass extends MyClass {}

the annotation processing fails if we call

myClass.getEnclosedElements()

and MyClass$MyInterface.class is not present. The processing is OK, if MyClass$MyInterface.class is present.

(original problem)


Solution

  • My question is: should the exported binary (jar) contain the MyClass$MyInterface.class file or not?

    It should.

    13.1. The Form of a Binary:

    1. Every class must contain symbolic references to all of its member types, and to all local and anonymous classes that appear in its methods, constructors, static initializers, instance initializers, and field initializers.

    4.7.6. The InnerClasses Attribute:

    If a class or interface has members that are classes or interfaces, its constant_pool table (and hence its InnerClasses attribute) must refer to each such member, even if that member is not otherwise mentioned by the class.

    So MyClass must have a reference to MyInterface. And although I don't have a citation for this, it would seem that if there are references to a particular class, then that class should be compiled.