一、注解的基本概念
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {
}
Annotation
(注解,也叫元数据)是一种应用于类、方法、参数、变量、构造器及包声明中的特殊修饰符,即描述数据的数据。
Java自带有四种内置注解 (定义在java.lang
中):
注解名称 | 作用 |
---|---|
@Override |
表示当前方法将覆盖父类中的方法,主要用于保证方法签名和拼写的准确性。 |
@Deprecated |
表示已被废弃,如果使用了被它注解的元素,会被警告。 |
@SuppressWarnings |
关闭编译器的警告信息 |
@SafeVarargs |
表示该方法参数长度可变 |
Java还提供了四种元注解(定义在java.lang.annotation
),用于新注解的创建:
注解名称 | 作用和可能的参数 |
---|---|
@Documented |
表示注解将被保存在Javadoc中,无参数 |
@Retention |
表示在什么级别保存注解信息(注解的生命周期),可能的RetentionPolicy 参数:SOURCE :只保存在源代码中,编译时将被编译器丢弃(例如@Override 和@SuppressWarnings )CLASS :默认项,会被保存在class文件中,但运行时会被虚拟机丢弃RUNTIME :会被保存在class文件中,运行时被虚拟机保留,并通过反射机制读取信息(例如@Deprecated 和@SafeVarargs ) |
@Target |
表示注解可用于什么地方,可能的ElementType 参数:TYPE :类、接口(包括注解)、enumFIELD :域声明(包括enum实例)METHOD :方法声明PARAMETER :参数声明CONSTRUCTOR :构造器声明LOCAL_VARIABLE :局部变量声明ANNOTATION_TYPE :注解声明PACKAGE :包声明 |
@Inherited |
允许子类继承父类中的注解,无参数 |
更多的注解体现在第三方库(如ButterKnife、Retrofit)和Android(如@Nullable)中。
二、详解元注解
@Documented
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.ANNOTATION_TYPE)
public @interface Documented {
}
表示注解将被保存在Javadoc中
什么是Javadoc?javadoc是Sun公司提供的一个技术,它可以从源代码中抽取类、方法、成员等注释形成一个和源代码配套的API帮助文档。
举个栗子:
先自定义一个注解,并用@Documented
修饰:
@Documented
@interface DocumentedAnnotation {
String name() default "name";
int age() default 0;
}
再创建一个类,并在类和方法前加上自定义的注解:
@DocumentedAnnotation(name = "Rimson", age = 18)
public class DocumentedAnnotationTest {
@DocumentedAnnotation(name = "Rimson", age = 18)
public String toString() {
return "hello";
}
}
接着生成Javadoc文件,笔者使用的是IDEA编译器(也可以直接使用javadoc命令生成),选择菜单栏-> Tools -> Genetate JavaDoc...,选中Whole project并指定Output directory,然后选择OK,不管是这种方式还是javadoc命令行,都能看到以下内容:
在刚才选择的目录中,找到index.html并打开,可以看到类和方法都显示在这个javadoc文件中:
如果去掉自定义注解中的@Documented
,再生成javadoc:
自定义注释将不会出现在javadoc中。同理,即使在代码中的toString()
方法加上@Override
注解,javadoc中也不会出现该注解,因为@Override
这个注解本身并没有被加上@Documented
。
@Retention
用来表示注解的保留策略(声明周期)
-
SOURCE
:源码级别,注解只保留在源文件阶段,当.java文件被编译成.class文件时,注解就会被去掉。这种声明周期的注解,常常用于检验代码规范,提示代码错误等等,被编译之后它们就不再起作用。例如@Override
和@SuppressWarnings
只是在编写源代码时,帮助编程人员检验方法签名是否准确以及去除不必要的警告。 -
CLASS
:字节码级别,注解保留到字节码文件阶段,当JVM通过ClassLoader向内存中加载字节码文件时,注解就会被去掉;这种生命周期主要运用在,某些需要对字节码进行处理的场合。 -
RUNTIME
:运行时级别,上面两种保留策略在运行时都会被去掉,也就是不能通过反射机制,调用getAnnotation
或getAnnotations
获取注解的内容;只有这种策略的注解,当JVM运行时,可以获取内容并得到执行。主要用于注解信息非常重要的场合,例如Butterknife的注解。
@Target
表示可以被注解修饰的内容。
@Inherited
加上此注解后的注解,可以被子注解继承。
网友评论