【注解与反射】7 - 1 注解
§7-1 注解
7-1.1 注解入门
注解(annotation)是自 JDK 5.0 引入的技术。注解不是程序本身,但可用于解释程序(这一点与注释相同),且能够被程序和编译器读取(例如反射读取)。
注解的格式为:
@AnnotationMame // 无参注解
@AnnotationName(param0 = val0, param1 = val1, ...) // 注解可带参数
注解可在包、类、方法和字段上使用,相当于为它们添加额外的辅助信息,具有检查和约束的作用,可以通过反射机制访问这些注解的数据。
注解通常已由框架在底层实现,一般而言无需自定义。
7-1.2 常见内置注解
最早在介绍方法重写时,就已经接触到注解。Java 中内置了一些常见的注解。
注解 | 说明 |
---|---|
@Override |
表示方法重写自超类或实现接口的方法。编译器会检查方法是否重写,若不是,编译器抛出错误信息。 |
@Deprecated |
表示方法已弃用。这些方法可能处于安全性被弃用,或已有更好的替代方案。该注解含带默认值的参数。 |
@SuppressWarnings |
用于抑制编译时的警告信息。该注解含无默认值的参数。 |
@FunctionalInterface |
表示接口为函数式接口。编译器会检查接口是否有且仅有一个抽象方法,否则会抛出错误信息。 |
其中,@Deprecated
和 @SuppressWarnings
接受参数。下表依次列出了这两个注解所接受的参数。
@Deprecated
接受的参数:
参数名 | 说明 | 示例 | 默认值 |
---|---|---|---|
boolean forRemoval |
表明被注解元素是否可能在未来版本中移除 | Object 的 finalize() 方法 |
false |
String since |
表明被注解元素自哪个版本开始被弃用 | Object 的 finalize() 方法 |
"" |
@SupressWarnings
接受的参数:
参数名 | 说明 | 示例 |
---|---|---|
String[] value |
由编译器抑制的警告组 | java.lang.SecurityManager ,@SuppressWarnings("removal") |
该参数指定编译器抑制的警告类型,接受以下值:
all
:抑制所有警告;unchecked
:抑制非受查警告;deprecation
:抑制被弃用元素警告;removal
:抑制移除元素警告;preview
:抑制预览功能警告;
一般而言,不建议手动添加该注解。
7-1.3 元注解
元注解(meta-annotation)是使用在注解上的注解,它约束了注解的作用范围、生命周期等行为。常见的元注解有 4 个。
-
@Target(value = {...})
:定义注解的适用范围。该元注解必须接受一个参数
ElementType[] value
,这是一个枚举类数组。这些枚举类常量定义了注解的适用范围。枚举常量 说明 ANNOTATION_TYPE
适用于注解 CONSTRUCTOR
适用于构造器 FIELD
适用于字段(含枚举常量) LOCAL_VARIABLE
适用于局部变量 METHOD
适用于方法 MODULE
适用于模块 PACKAGE
适用于包 PARAMETER
适用于形式参数 RECORD_COMPONENT
适用于记录类 TYPE
适用于类、接口、注解、枚举类或记录类 TYPE_PARAMETER
适用于泛型的类型参数 TYPE_USE
适用于任意类型名称(含 TYPE_PARAMETER
的适用范围)示例:
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD})
-
@Retention(value)
:定义注解的生命周期。该元注解必须接受一个参数
RetentionPolicy value
以定义注解的生命周期。该类也是一个枚举类,这些枚举常量定义了注解的生命周期。枚举常量 说明 SOURCE
注解仅保留在源代码,编译阶段被编译器丢弃 CLASS
编译器在编译阶段保留注解,但不会在 VM 运行时保留(默认值) RUNTIME
注解在编译阶段和运行时阶段均被保留,因此可用反射读取 可见,注解的生命周期为
SOURCE < CLASS < RUNTIME
。 -
@Documented
:定义是否生成该注解的 JavaDoc 文档。 -
@Inherited
:定义子类能否继承父类的该注解。
7-1.4 自定义注解
注解,又称注解接口,其定义方式是使用关键字 @interface
。为有效区别于接口,注解的生命必须要有 @
这一个字符。
自定义注解的格式为:
public @interface AnnotationName {}
这是声明一个最简单注解的方法。也可以为注解添加参数,其格式为:
public @interface AnnotationName {
Type value();
Type parameterName();
Type defaultParameter() default val;
...
}
为注解声明参数时,要注意:
- 参数类型只能为基本数据类型、
Class
、String
、枚举类或它们的一维数组; - 参数默认具有访问修饰符
public
,可省略; - 参数后必须带有括号
()
; - 注解的参数必须有值,若要为参数设定默认值,要使用
default
关键字分配默认值; - 若只有一个参数成员,可将其命名为
value
,此时,为注解参数赋值时,value =
可省略;