1、自定义Annotation类型
(1)定义Annotation类型
l 使用@interface声明Annotation类型
public @interface InProgress {
}
l 使用Annotation类型
public class TestAnnotation {
@InProcess
public void test() {
}
}
l 如果Annotation类型和使用它的类不在相同的包中,可以import Annotation类型,以便直接使用 @InProgress
(2)添加成员
l Annotation类型可以有成员变量,以提供有用的信息
l 定义数据成员不需要定义getter和setter方法,只需要定义一个以成员名称命名的方法,并指定返回类型为需要的数据类型
l 简单的例子:
public @interface TODO {
String value();
}
l 使用带成员的Annotation类型:
public class TestAnnotation {
@InProcess
@TODO("Need to finish this method later")
public void test() {
}
}
(3)设置缺省值
l 要为Annotation类型的成员设置缺省值,需要在声明成员时使用default关键字:
public @interface GroupTODO {
public enum Severity {
CRITICAL, IMPORTANT, TRIVIAL, DOCUMENTATION
};
Severity severity() default Severity.IMPORTANT;
String item();
String assignedTo();
String dateAssigned();
}
l 当然,缺省值的类型必须与成员变量声明的类型完全相同
l 下面是使用缺省值的例子:
public class TestAnnotation {
@InProcess
@GroupTODO(
item="Need to finish this method later",
assignedTo="nelson_tu",
dateAssigned="2005/02/05"
)
public void test() {
}
}
l 下面是改写缺省值的例子:
public class TestAnnotation {
@InProcess
//@TODO("Need to finish this method later")
@GroupTODO(
severity=GroupTODO.Severity.DOCUMENTATION,
item="Need to finish this method later",
assignedTo="nelson_tu",
dateAssigned="2005/02/05"
)
public void test() {
}
}
2、元Annotation
l 元Annotation就是Annotation的Annotation,JDK5提供了4种预定义的元Annotation
(1)@Target
l @Target指定Annotation类型可以应用的程序元素,以便在其它程序元素中误用Annotation类型
l 程序元素的类型由java.lang.annotation.ElementType枚举类定义:
package java.lang.annotation;
public enum ElementType {
TYPE, // Class, interface, or enum (but not annotation)
FIELD, // Field (including enumerated values)
METHOD, // Method (does not include constructors)
PARAMETER, // Method parameter
CONSTRUCTOR, // Constructor
LOCAL_VARIABLE, // Local variable or catch clause
ANNOTATION_TYPE, // Annotation Types (meta-annotations)
PACKAGE // Java package
}
l 下面是使用@Target的例子:
@Target({ElementType.TYPE,
ElementType.METHOD,
ElementType.CONSTRUCTOR,
ElementType.ANNOTATION_TYPE})
public @interface TODO {
String value();
}
(2)@Retention
l @Retention和 Java 编译器处理Annotation类型的方式有关
l 这些方式由java.lang.annotation.RetentionPolicy 枚举类定义:
package java.lang.annotation;
public enum RetentionPolicy {
SOURCE, // Annotation is discarded by the compiler
CLASS, // Annotation is stored in the class file, but ignored by the VM
RUNTIME // Annotation is stored in the class file and read by the VM
}
l 使用@Retention的例子参看后面的@Documented
(3)@Documented
l @Documented指明需要在Javadoc中包含Annotation(缺省是不包含的)
l 下面是一个使用@Documented的例子:
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface InProcess {
}
l 使用@Documented的一个技巧就是指定保持性策略为RetentionPolicy.RUNTIME:这样,Annotation就会保留在编译后的类文件中并且由虚拟机加载,然后Javadoc就可以抽取出Annotation,添加到类的HTML文档中
(4)@Inherited
l @Inherited最复杂、使用最少、也最容易造成混淆的一个
l 假设使用@InProgress 标记一个正在开发的类,只要正确应用@Documented,Annotation信息就会出现在Javadoc中;现在要编写一个新类,扩展那个正在开发的类,那么使用子类,或者查看它的文档,根本没法表明还有什么地方没有完成;而本来是希望@InProgress 的Annotation信息会被带到子类中,这就需要使用@Inherited了
l 下面是这样的例子:
@Documented
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface InProcess {
}