作者:曾巧(numenzq )
摘要
在之前的文章中,我们已经了解了Annotation 的基本概念,Java 的内置Annotation 和如何定制自己的Annotation ;在这里我们将学习Annotation 的另一个特性:元注释,它可以使我们更好的定制我们的注释。
内容
l 限定注释使用范围
l 注释保持性策略
l 文档化功能
l 标注继承
l 概要
限定注释使用范围
当我们的自定义注释不断的增多也比较复杂时,就会导致有些开发人员使用错误,主要表现在不该使用该注释的地方使用。为此,Java 提供了一个ElementType 枚举类型来控制每个注释的使用范围,比如说某些注释只能用于普通方法,而不能用于构造函数等。下面是Java 定义的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
}
下面我们来修改Greeting 注释,为之添加限定范围的语句,这里我们称它为目标(Target )使用方法也很简单,如下:
package com.gelc.annotation.demo.customize;
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
public enum FontColor {
RED, GREEN, BLUE
};
String name();
String content();
FontColor fontColor() default FontColor.BLUE;
}
正如上面代码所展示的,我们只允许Greeting 注释标注在普通方法和构造函数上,使用在包申明、类名等时,会提示错误信息。
注释保持性策略
在Java 编译器编译时,它会识别在源代码里添加的注释是否还会保留,这就是RetentionPolicy 。下面是Java 定义的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
}
RetentionPolicy 的使用方法与ElementType 类似,简单代码示例如下:
package com.gelc.annotation.demo.customize;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
public enum FontColor {
RED, GREEN, BLUE
};
String name();
String content();
FontColor fontColor() default FontColor.BLUE;
}
文档化功能
Java 提供的Documented 元注释跟Javadoc 的作用是差不多的,其实它存在的好处是开发人员可以定制Javadoc 不支持的文档属性,并在开发中应用。它的使用跟前两个也是一样的,简单代码示例如下:
package com.gelc.annotation.demo.customize;
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;
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
public @interface Greeting {
public enum FontColor {
RED, GREEN, BLUE
};
String name();
String content();
FontColor fontColor() default FontColor.BLUE;
}
值得大家注意的是,如果你要使用@Documented 元注释,你就得为该注释设置RetentionPolicy.RUNTIME 保持性策略。为什么这样做,应该比较容易理解,这里就不提了。
继承应该是Java 提供的最复杂的一个元注释了,它的作用是控制注释是否会影响到子类, 简单代码示例如下:
package com.gelc.annotation.demo.customize;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
@Target( { ElementType.METHOD, ElementType.CONSTRUCTOR })
FontColor fontColor() default FontColor.BLUE;
你一定已经感受到元注释的好处和作用了吧,它可以让我们定制的注释功能更明确,约束性更强等好处;在下一篇文章中,我们将学习通过反射来获得这些注释信息。