What is the point of defining enums and fields inside annotation declarations?

It seems that it is possible to declare fields and enums inside an annotation declaration in Java. For example javac compiles this:

 @interface ClassPreamble {
   public enum AnEnum {
        Value;
   }
   String aField = "";

   String author();
   String date();
   String currentRevision() default "";
   String lastModified() default "N/A";
   String lastModifiedBy() default "N/A";
   // Note use of array
   String[] reviewers();
}

      

What is the point / usefulness of defining enums and fields inside annotation declarations?

thank

+3


source to share


1 answer


Java annotations are just interfaces that inherit java.lang.annotation.Annotation

(*) and are handled to some extent by the compiler, but the compiler won't stop you from doing whatever is legal in the interfaces. It might even be helpful (see example from the JLS at the bottom of this answer).

(*) Although the interface that manually extends Annotation

does not define the type of annotation (source: javadoc for Annotation.java

)

Your annotation is ClassPreamble

efficient interface ClassPreamble extends java.lang.annotation.Annotation

(decompile it to see).

Legally declare the enumeration in the interface. Legally declare a field in an interface: it will be implicitly public static final.

$ cat Funny.java 
interface Funny {
  public enum AnEnum { One, Two }
  String aField = "";
}

$ javac Funny.java 

$ javap -c Funny.class
Compiled from "Funny.java"
interface Funny extends java.lang.annotation.Annotation {
  public static final java.lang.String aField;

}

$ javap -c Funny\$AnEnum.class | head
Compiled from "Funny.java"
public final class Funny$AnEnum extends java.lang.Enum<Funny$AnEnum> {
  public static final Funny$AnEnum One;

  public static final Funny$AnEnum Two;

  public static Funny$AnEnum[] values();
    Code:
       0: getstatic     #1                  // Field $VALUES:[LFunny$AnEnum;
       3: invokevirtual #2                  // Method "[LFunny$AnEnum;".clone:()Ljava/lang/Object;
...

      



I'm not sure if there is a good answer to the question: "What is the point of such constructions?" I guess it was implemented this way as a design choice: whatever the annotation does is coded as bytecode for the interface, which the JVM knows how to deal with, so they didn't have to modify the JVM too much ( if at all), it allowed the desired functionality for compile time and runtime, and it does no harm (or does it?).

Edit: 2 excerpts from Section 9.1 of the Java Language Specification about annotations (which refers to Chapter 9 about interfaces):

An annotation type declaration specifies a new annotation type — a special kind of interface type. To distinguish an annotation type declaration from a regular interface declaration, the keyword interface is preceded by an at (@) sign.

[...]

The grammar for annotation type declarations allows other element declarations besides method declarations. For example, one could declare a nested enum for use in conjunction with the annotation type:

@interface Quality {
    enum Level { BAD, INDIFFERENT, GOOD }
    Level value();
}

      

+1


source







All Articles