在注释声明中定义枚举和字段的含义是什么?

时间:2017-04-17 19:51:26

标签: java

似乎可以在Java中的注释声明中声明字段和枚举。例如,javac编译:

 @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();
}

在注释声明中定义枚举和字段的含义/用途是什么?

由于

1 个答案:

答案 0 :(得分:1)

Java注释只是继承java.lang.annotation.Annotation(*)的接口,并且在一定程度上由编译器专门处理,但编译器不会阻止您在接口中做任何合法的事情。它甚至可能很有用(参见本答案底部的JLS示例)。

(*)虽然手动扩展Annotation的界面没有定义注释类型(Annotation.java来源:javadoc

您的注释ClassPreamble实际上是interface ClassPreamble extends java.lang.annotation.Annotation(反编译以便查看)。

在接口中声明枚举是合法的。 在接口中声明一个字段是合法的:它将隐式地为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;
...

我不确定“这种结构的含义是什么?”有一个很好的答案。我猜它是以这种方式实现的一种设计选择:无论注释做什么都编码为接口的字节码,JVM知道如何处理,因此他们不需要过多地修改JVM本身(如果有的话) ,它允许编译时和运行时所需的功能,它不会造成伤害(或者是吗?)。

编辑:来自Java Language Specification section 9.6 about annotations的2个摘录(属于关于接口的第9章):

  

注释类型声明指定新的注释类型,一种特殊的接口类型。为了区分注释类型声明和普通接口声明,关键字接口前面有一个at符号(@)。

     

[...]

     

注释类型声明的语法允许除方法声明之外的其他元素声明。例如,可以选择声明嵌套枚举以与注释类型结合使用:

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