简体   繁体   中英

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

It seems it is possible to declare fields and enums inside the declaration of an annotation 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 meaning / usefulness of defining enums and fields inside annotation declarations?

Thanks

Java annotations are just interfaces that inherit java.lang.annotation.Annotation (*), and are treated specially by the compiler to a certain extent, but the compiler will not prevent you from doing whatever is legal within interfaces. It can even be useful (see example from JLS at bottom of this answer).

(*) Although an interface that manually extends Annotation does not define an annotation type (source: javadoc for Annotation.java )

Your annotation ClassPreamble is effectively interface ClassPreamble extends java.lang.annotation.Annotation (decompile it to take a look).

It is legal to declare an enum within an interface. It is legal to 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 there is a good answer for "what is the meaning of such constructs?". I guess it was implemented this way as a design choice: whatever the annotation does is encoded as bytecode for an interface, which the JVM knows how to deal with, so they did not need to modify the JVM itself too heavily (if at all), it allowed the desired features for compile-time and for run-time, and it does not do harm (or does it?).

Edit: 2 extracts from the Java Language Specification section 9.6 about annotations (which belongs 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 normal interface declaration, the keyword interface is preceded by an at-sign (@).

[...]

The grammar for annotation type declarations permits other element declarations besides method declarations. For example, one might choose to declare a nested enum for use in conjunction with an annotation type:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM