Java基础-元注解

Annotation(注解)

从JDK 1.5开始, Java增加了对元数据(MetaData)的支持,也就是 Annotation(注解)。

注解其实就是代码里的特殊标记,它用于替代配置文件:传统方式通过配置文件告诉类如何运行,有了注解技术后,开发人员可以通过注解告诉类如何运行。在Java技术里注解的典型应用是:可以通过反射技术去得到类里面的注解,以决定怎么去运行类。

注解可以标记在包、类、属性、方法,方法参数以及局部变量上,且同一个地方可以同时标记多个注解。 如下是Java基础注解中的3个常用注解:

1
2
3
4
5
6
7
8
// 抑制编译期的未指定泛型、未使用和过时警告
@SuppressWarnings({ "rawtypes", "unused", "deprecation" })

// 重写
@Override

//提示程序中的元素不在建议使用
@Deprecated

meta-annotation(元注解)

除了直接使用JDK 定义好的注解,我们也可以自己写想要的注解,在JDK 1.5中提供了4个标准的用来对注解类型进行注解的注解类,我们称之为 meta-annotation(元注解),分别是:

  • @Target
  • @Retention
  • @Documented
  • @Inherited

下面介绍一下这4个注解类的作用。

@Target注解

Target注解的作用是:描述注解的使用范围。
Target注解用来说明那些被它所注解的注解类可修饰的对象范围:注解可以用于修饰 packages、types(类、接口、枚举、注解类)、类成员(方法、构造方法、成员变量、枚举值)、方法参数和局部变量(如循环变量、catch参数),它的取值范围定义在 ElementType枚举中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public enum ElementType {

TYPE, // 类、接口、枚举类

FIELD, // 成员变量(包括:枚举常量)

METHOD, // 成员方法

PARAMETER, // 方法参数

CONSTRUCTOR, // 构造方法

LOCAL_VARIABLE, // 局部变量

ANNOTATION_TYPE, // 注解类

PACKAGE, // 可用于修饰:包

TYPE_PARAMETER, // 类型参数,JDK 1.8 新增

TYPE_USE // 使用类型的任何地方,JDK 1.8 新增

}

@Retention注解

Reteniton注解的作用是:描述注解保留的时间范围。一共有三种选择,定义在RetentionPolicy枚举中。

1
2
3
4
5
6
public enum RetentionPolicy {

SOURCE, // 源文件保留
CLASS, // 编译期保留,默认值
RUNTIME // 运行期保留,可通过反射去获取注解信息
}

这三个选项的生命周期长度 SOURCE < CLASS < RUNTIME ,所以前者能作用的地方后者一定也能作用。一般如果需要在运行时去动态获取注解信息,那只能用 RUNTIME 注解;如果要在编译时进行一些预处理操作,比如生成一些辅助代码(如 ButterKnife),就用 CLASS注解;如果只是做一些检查性的操作,比如 @Override 和 @SuppressWarnings,则可选用 SOURCE 注解。

@Documented注解

Documented注解的作用是:描述在使用 javadoc 工具为类生成帮助文档时是否要保留其注解信息。

为了验证Documented注解的作用到底是什么,我们创建一个带有 @Documented 的自定义注解类。

1
2
3
4
5
6
7
8
9
10
11
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Documented
@Target({ElementType.TYPE,ElementType.METHOD})
public @interface MyDocumentedtAnnotation {

public String value() default "这是@Documented注解为文档添加的注释";

}

再创建一个 MyDocumentedTest 类。

1
2
3
4
5
6
7
8
9
@MyDocumentedtAnnotation
public class MyDocumentedTest {

@Override
@MyDocumentedtAnnotation
public String toString() {
return this.toString();
}
}

接下来,使用以下命令为 MyDocumentedTest 类生成帮助文档。

命令执行完成之后,会在当前目录下生成一个 doc 文件夹,其内包含以下文件。

查看 index.html 帮助文档,可以发现在类和方法上都保留了 MyDocumentedtAnnotation 注解信息。

如果去掉上面的上面的 @Documented 注解,再重复上面的过程得到的文档上就没有MyDocumentedtAnnotation这个注解了。

@Inherited注解

Inherited注解的作用是:使被它修饰的注解具有继承性(如果某个类使用了被@Inherited修饰的注解,则其子类将自动具有该注解)。

------ 本文完 ------