直接Annations

一、介绍

本系列文章的这一部分我们将会介绍Java 5版本引入的除泛型和枚举之外的另外一个强大特性:注解,可以将注解看成一种特殊的接口。

注解是一种特殊种类的元数据,它能够关联Java语言中不同元素和结构。有意思的是,在Java生态系统中大多数使用样板XML描述符的地方,注解在消除这些XML描述符上做出了很大的贡献。注解引入了新的,类型安全以及非常强健的配置和个性化技术。

二、注解作为特殊接口

就像我们在前文中所提到的一样,注解用来关联Java语言中的元数据和不同的元素。

注解本身对它所注解的元素不会造成任何直接的影响。但是,依靠注解和它的定义方式,它们可以被Java编译器(注解最好的实例就是我们前面的文章中所使用的@Override注解)、注解处理器和运行时代码使用反射和其他的虚拟机内省技术使用。

让我们来看一个最简单的注解声明:

public @interface SimpleAnnotation {
}
@interface关键字引入了新的注解类型,这也是为何注解可以被当做专门的接口看待,注解可以声明有默认值和没有默认值的属性,比如:

public @interface SimpleAnnotationWithAttributes {
String name();
int order() default 0;
}
如果注解声明了没有默认值的属性,那么在该注解被应用的所用地方都应该提供注解属性值。

@SimpleAnnotationWithAttributes(name = "new annotation")
为了方便,如果注解只有一个属性并且属性的名称是value,那么属性的名称就可以被省略,比如:

public @interface SimpleAnnotationWithValue {
String value();
}
上面声明的这个注解就可以按照如下的方式去使用:

@SimpleAnnotationWithValue("new annotation")
1
注解也有一些限制,在某些情况下使用注解可能会不太方便。

首先,注解不支持任何继承:注解不能继承其他的注解。

其次,不能通过编码的形式使用new关键字创建注解实例。

第三,注解只能声明基本数据类型属性,String或者 Class<?>类型及其数组。

第四,注解中不允许声明方法和构造器。

三、注解及其保留策略(Retention Policy)

每个注解都有一个被称为保留策略(Retention Policy)的特征,它是一组如何保留注解的策略组合的枚举(RetentionPolicy类型)。保留策略可以设置为以下的值之一。

策略 描述
CLASS 注解被编译器记录在class文件中,但是在运行时不需要虚拟机保留(即运行时不存在)
RUNTIME 注解被编译器记录在class文件中并且在运行时被虚拟机保留,因此可以通过反射机制获取
SOURCE 注解被编译器丢弃(即注解仅在源码中保留,class文件中不存在)
保留策略对注解何时可用于处理有至关重要的影响。保留策略可以通过使用@Retention注解来设置。比如:

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention( RetentionPolicy.RUNTIME )
public @interface AnnotationWithRetention {
设置注解的保留策略为RUNTIME将会保证注解在编译过程和运行的应用程序中存在。

四、注解以及元素类型(ElementType)

注解的另外一个特征就是每个注解必须有它能够应用的元素类型。有点类似于保留策略,元素类型被定义成一组可能的元素类型的枚举(ElementType)。

元素类型 描述
ANNOTATION_TYPE 标明注解可用于注解类型声明(应用于另外的注解)
CONSTRUCTOR 标明注解可用于构造函数声明
FIELD 标明注解可用于字段/域(包括枚举常量)声明
LOCAL_VARIABLE 标明注解可用于局部变量声明
METHOD 标明注解可用于方法声明
PACKAGE 标明注解可用于包声明
PARAMETER 标明注解可用于参数声明
TYPE 标明注解可用于类、接口(包括注解类型)、枚举类型的声明
此外,除了上面所描述的这些元素类型之外,Java 8版本引入了两个新的注解可以使用的元素类型。

元素类型 描述
TYPE_PARAMETER 标明注解可以写在类型变量的声明语句中
TYPE_USE 表示该注解能写在使用类型的任何语句中(eg:声明语句、泛型和强制转换语句中的类型)
和保留策略对比,注解可以使用@Target注解声明多个与之相关联的多个元素类型。比如:

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

@Target({ElementType.FIELD, ElementType.METHOD})
public @interface AnnotationWithTarget {
}
大多数情况下,您要创建的所有注解都应该同时指定保留策略和元素类型才能有用。

posted @ 2019-03-24 22:05  Python机器猫  阅读(209)  评论(0编辑  收藏  举报