Java Annotation
Java SE 5.0 开始引入Annotation(标记)新语法特性。Annotation用于修饰包、类型(类、接口、enum)、方法、属性、变量、参数等,为上述被修饰的对象提供metadata。Annotation本身是一种接口(inerface)类型。
作为Annotation的一个应用实例,Servlet 3.0规范中定义了 @WebServlet Annotation,用于取代web.xml 描述文件中的<servlet>和<servlet-mapping>。例如,以下的Servlet声明
<servlet> <display-name>...</display-name> <servlet-name>...</servlet-name> <servlet-class>your.ServletClass</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>...</servlet-name> <url-pattern>/mapping/url</url-pattern> </servlet-mapping>
可使用@WebServlet 在源代码中直接进行声明,如下:
package your; ... @WebServlet(name="...", displayName="...", urlPatterns = {"/mapping/url"}, loadOnStartup=1) public class ServletClass extends HttpServlet { ...
1,Annotation 的定义
Annotation的定义类似于接口的定义,但有以下不同/限制:
- interface关键字必须加@前缀,即 @interface
- 方法不得有参数和throws
- 方法返回值类型为以下之一:基本数据类型、String、Class、enum、Annotation,以及这些类型的数组
- 方法可以有默认值,用 default 关键字声明
- 如果只有一个方法,方法名必须为value
Annotation的方法称为element。下面是一个示例Annotation的定义:
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.ElementType; /** * This annotation should be used only on methods. */ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface DemoMethodAnnotation {
int anIntElement();
String aStringElement();
String anotherStringElement() default "whatever";
String aArrayOfStringsElement();
}
上面的例子中,Annotation的定义本身也应用了2个Annotation:@Retention和@Target。关于这2个Annotation及其element,可参考它们的 API Doc。
2,Annotation的使用
Annotation是作为修饰符使用的,因此,基本上,其他修饰符(如public、static、final...)可使用的地方就可以使用Annotation。Annotation的一般声明格式为:
@AnnotationName(elementName1=value1, elementName2=value2, ...)
但有如下的限制或特例:
- element 值必须是编译时的常量
- 定义为具有默认值的element可省略,将使用其默认值
- 空element列表(())可省略,即只声明 @AnnotationName
- 如果仅有一个element(其名称为value),可省略value=,即 @AnnotationName(theValue)
3,通过反射在运行时读取Annotation信息
通过以下API读取Annotation信息:
- 接口 java.lang.reflect.AnnotatedElement,此接口的实现类有Package、Class、Method、Constructor、Field等(你懂的)