Java的注解(Annotation)

1. 什么是注解

Annotation is code about the code, that is metadata about the program itself.

Java 注解,是 Java5.0 引入的一种插入源代码中用于某种工具处理的标签。注解不会改变程序的编译方式和运行结果,但能被编译器、注解工具或其他工具解析。

 

 

2. 注解的使用

在一般的 Java 开发中,最常接触到的可能就是@Override@SupressWarnings这两个注解了。使用 @Override 的时候只需要一个简单的声明即可。这种称为标记注解(marker annotation ),它的出现就代表了某种配置语义。

其它的注解是可以有自己的配置参数的。配置参数以名值对的方式出现。使用 @SupressWarnings 的时候需要类似 @SupressWarnings({"uncheck", "unused"}) 这样的语法。在括号里面的是该注解可供配置的值。由于这个注解只有一个配置参数,该参数的名称默认为 value,并且可以省略。而花括号则表示是数组类型。如:

public interface IPlatformProperties {
@Value(</span>"database.url"<span style="color: rgba(0, 0, 0, 1)">)
String databaseURL();

@Value(</span>"database.login"<span style="color: rgba(0, 0, 0, 1)">)
String databaseLogin();

@Value(</span>"database.mac"<span style="color: rgba(0, 0, 0, 1)">)
String databaseMAC();

@Value(</span>"publisher.from.socket"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">boolean</span><span style="color: rgba(0, 0, 0, 1)"> isFromSocket();

@Value(</span>"publisher.buffersize"<span style="color: rgba(0, 0, 0, 1)">)
</span><span style="color: rgba(0, 0, 255, 1)">int</span><span style="color: rgba(0, 0, 0, 1)"> ringbufferSize();

}

 

 

3. 注解的语法

每个注解必须通过一个注解接口进行定义,接口中的方法与注解中的元素相对应。例如:

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Value {
</span><span style="color: rgba(0, 128, 0, 1)">/**</span><span style="color: rgba(0, 128, 0, 1)">
 * The actual value expression: e.g. "#{systemProperties.myProp}".
 </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
String value();

}

又或者带有默认值的注解定义:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Assignment {String assignee();
    int effort();
    double finished() default 0;
} 

@interface 用来声明一个注解,其中的每一个方法实际上是声明了一个配置参数。方法的名称就是参数的名称,返回值类型就是参数的类型。可以通过 default 来声明参数的默认值。在这里可以看到@Retention@Target这样的元注解,用来声明注解本身的行为。@Retention 用来声明注解的保留策略,有CLASSRUNTIMESOURCE这三种,分别表示注解保存在类文件、JVM 运行时刻和源代码中。只有当声明为 RUNTIME 的时候,才能够在运行时刻通过反射 API 来获取到注解的信息。@Target 用来声明注解可以被添加在哪些类型的元素上,如类型、方法和域等。

一个例子,如 @Override 里面的 Retention 设为 SOURCE, 编译成功了就不要这一些检查的信息; 相反,@Deprecated 里面的 Retention 设为 RUNTIME, 表示除了在编译时会警告我们使用了哪个被 Deprecated 的方法, 在执行的时候也可以查出该方法是否被 Deprecated。

除了@Retention@Target这样的元注解,还有@Documented 和 @Inherited 这两个注解。

 

 

4. 处理注解

根据,@Retention 元注解的定义,注解可以在编译期间和运行时处理。一般来说,在运行时利用反射,取得注解的具体值,然后进行处理,例子在这里。编译期间的注解处理还没遇过,不过可以参考这里的例子。

 

本文完

 

参考:

http://javapapers.com/core-java/java-annotations/

http://www.infoq.com/cn/articles/cf-java-annotation

http://www.iteye.com/topic/36659