5. Annotation(注解)java
Annotation是一种元数据(metadata),即“Information about information”,在源代码中标记。数组
注解使用类Javadoc的语法,@ANNOTATION_NAME(参数),参数为KEY=VALUE的形式。ide
5.1 内置注解类型this
内置的注解类型位于java.lang包中,不需导入,开箱即用。spa
5.1.1. Overridecode
标明方法覆写了基类的方法。此注解为一种标识注解,无参数。orm
JDK源码以下:继承
@Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { }
5.1.2. Deprecated接口
代表不推荐使用。此注解为一种标识注解,无参数。ip
JDK源码以下:
@Documented @Retention(RetentionPolicy.RUNTIME) public @interface Deprecated { }
5.1.3. SuppressWarnings
关闭类、方法、属性等的指定编译器警告。此注解接收一个String[]类型的参数。
JDK源码以下:
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE}) @Retention(RetentionPolicy.SOURCE) public @interface SuppressWarnings { String[] value(); }
SuppressWarnings注解用法示例:
@SuppressWarnings(value={"unchecked"}) public void nonGenericsMethod( ) { List list = new ArrayList( ); list.add("foo"); }
5.2 注解的注解
注解的注解即描述元数据的元数据,如上述注解的JDK源代码中的注解。
5.2.1 Target
标明注解能够做用的目标范围。
JDK源码以下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType[] value(); }
其中ElementType的取值为:
TYPE:类、接口(包含注解)、枚举类型
FIELD:属性(包含枚举类型的值)
METHOD:方法
PARAMETER:方法参数
CONSTRUCTOR:构造方法
LOCAL_VARIABLE:局部变量
ANNOTATION_TYPE:注解类型
JDK源代码:
public enum ElementType { /** Class, interface (including annotation type), or enum declaration */ TYPE, /** Field declaration (includes enum constants) */ FIELD, /** Method declaration */ METHOD, /** Parameter declaration */ PARAMETER, /** Constructor declaration */ CONSTRUCTOR, /** Local variable declaration */ LOCAL_VARIABLE, /** Annotation type declaration */ ANNOTATION_TYPE, /** Package declaration */ PACKAGE }
5.2.2 Retention
标明注解能够保持的范围。
JDK源码以下:@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { RetentionPolicy value(); }
其中RetentionPolicy的取值为:
public enum RetentionPolicy { /** * Annotations are to be discarded by the compiler. */ SOURCE, /** * Annotations are to be recorded in the class file by the compiler * but need not be retained by the VM at run time. This is the default * behavior. */ CLASS, /** * Annotations are to be recorded in the class file by the compiler and * retained by the VM at run time, so they may be read reflectively. * * @see java.lang.reflect.AnnotatedElement */ RUNTIME }
5.2.3 Documented
标明Javadoc文档中需包含此注解内容。
JDK源码以下:
@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Documented { }
注:Documented注解的使用要求注解的RetentionPolicy的设置为RUNTIME
5.2.4 Inherited
标明做用于class上的注解是被自动继承的注解。
JDK源码以下:@Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Inherited { }
注意:
1. Inherited注解的使用要求注解的RetentionPolicy的设置为RUNTIME
2. 接口上的注解即便是标明了@Inherited的注解,也不会被继承
3. 基类方法上的注解若是标明了@Inherited则会被继承,但在被子类覆写后也会丢失注解信息
5.3 自定义注解类型
注解类型本质上是一种Java的接口,但使用@interface关键字进行声明。
示例:
public @interface Todo { public enum Severity {CRITICAL, IMPORTANT, TRIVIAL, DOCUMENTATION}; String description(); String assignedTo(); }
使用示例:
@Todo( severity=Todo.Severity.CRITICAL, description="Figure out the amount of order", assignedTo="Tom" ) public void calculate() { // Need to finish this method later }
5.5 新增的反射API
在java.lang.reflect包中新增了AnnotatedElement接口,JDK源码以下:
public interface AnnotatedElement { boolean isAnnotationPresent(Class<? extends Annotation> annotationClass); <T extends Annotation> T getAnnotation(Class<T> annotationClass); Annotation[] getAnnotations(); Annotation[] getDeclaredAnnotations(); }
reflect包中的相关类如Class等都实现了此接口。
注:反射要求注解的RetentionPolicy的设置为RUNTIME