12.4 注解(元数据)
从JDK 5开始,Java支持在源文件中嵌入补充信息,这类信息称为注解(annotation)。注解不会改变程序的动作,因此也就不会改变程序的语义。但是在开发和部署期间,各种工具可以使用这类信息。例如,源代码生成器可以处理注解。术语“元数据”(metadata)也用于表示这个特性,但是术语“注解”更具描述性并且更常用。
12.4.1 注解的基础知识
注解是通过基于接口的机制创建的。首先看一个例子。下面的代码声明了注解MyAnno:
首先,注意关键字interface前面的@,这告诉编译器正在声明一种注解类型。接下来,注意两个成员str()和val()。所有注解都只包含方法声明。但是,不能为方法提供方法体,而是由Java实现这些方法。此外,正如后面即将看到的,这些方法的行为更像是域变量。
注解不能包含extends子句。但是,所有注解类型都自动扩展了Annotation接口。因此,Annotation是所有注解的超接口。该接口是在java.lang.annotation包中声明的,其中重写了hashCode()、equals()以及toString()方法,这些方法是由Object类定义的。另外还指定了annotationType()方法,该方法返回表示所调用注解的Class对象。
在声明注解之后,就可以用来注解声明了。所有类型的声明都可以有一个与之关联的注解。例如,类、方法、域变量、参数以及枚举常量都可以带有注解。甚至注解本身也可以被注解。对于所有情况,注解都要放在声明的最前面。
应用注解时,需要为注解的成员提供值。例如,下面的例子将MyAnno应用到某个方法声明中:
这个注解被链接到方法myMeth()。下面进一步分析注解的语法。注解的名称以@作为前缀,后面跟一个位于圆括号中的成员初始化列表。为了给成员提供值,需要为成员的名称赋予值。所以在这个例子中,将字符串“Annotation Example”赋给MyAnno的str成员。注意在这条赋值语句中,在str之后没有圆括号。当为注解成员提供数值时,只使用成员的名称。因此,在这个上下文中,注解成员看起来像域变量。