乐者为王

Do one thing, and do it well.

实现自己的Java Annotation

Annotation类型的声明与一般的接口声明极其相似,区别只在于它在interface关键字前面使用“@”符号。下面就是一个简单的例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
@Documented
public @interface Event {
}

public class EventAnonationTest {
    @Event
    public void clicked() {
    }
}

@Target指定可以应用Annotation类型的程序元素,以防止在其它程序元素中误用Annotation类型:

1
2
3
4
5
6
7
8
9
10
public enum java.lang.annotation.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
}

@Retention设置Java编译器处理Annotation类型的方式:

1
2
3
4
5
public enum java.lang.annotation.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
}

@Documented指明需要在Javadoc中包含Annotation(缺省是不包含的)。使用@Documented的一个技巧就是指定Retention为RetentionPolicy.RUNTIME。这样,Annotation就会保留在编译后的类文件中并且由虚拟机加载,然后Javadoc就可以抽取出Annotation并添加到类的HTML文档中。

@Inherited定义了Annotation类型的修饰是否可以由被修饰类的子类继承。

Comments