定义
Java 注解(Annotation)是一种元数据形式,它为程序元素(类、方法、字段等)提供额外的说明信息。这些信息可以在编译时(如@Override
)、类加载时(如 Spring 的@Autowired
)或运行时(如 JUnit 的@Test
)被读取并执行特定逻辑。注解本身不会直接影响程序的运行,但可以被工具、框架或编译器利用,实现代码检查、自动化配置、文档生成等功能。
核心概念
1. 元数据的扩展
注解本质是一种结构化元数据,相比传统注释(//
或/* */
),它:
- 可以被编译器或运行时环境读取
- 支持参数化配置
- 用于实现特定功能逻辑
2. 语法特征
// 定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
String value() default ""; // 声明参数
int count() default 1;
}
// 使用注解
@MyAnnotation(value = "测试", count = 3)
public void myMethod() { ... }
3. 元注解(Meta-Annotation)
用于定义注解的注解,常见的有:
@Retention
:指定注解的生命周期(SOURCE/CLASS/RUNTIME)@Target
:指定注解可应用的程序元素类型@Documented
:将注解包含在 JavaDoc 中@Inherited
:允许子类继承父类的注解@Repeatable
(Java 8+):允许同一元素重复使用同一注解
@Target
的基本用法
@Target
是一个元注解(用于注解其他注解的注解),它用于指定被修饰的注解可以应用于哪些程序元素(如类、方法、字段等)。通过@Target
,可以精确控制注解的使用范围,增强注解的类型安全性。
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
@Target(ElementType.METHOD) // 该注解只能用于方法
public @interface MyMethodAnnotation {
String value() default "";
}
@Target({ElementType.TYPE, ElementType.FIELD}) // 可用于类/接口和字段
public @interface MyTypeOrFieldAnnotation {
int priority() default 1;
}
ElementType 值 | 描述 |
---|---|
TYPE |
类、接口(包括注解类型)或枚举声明 |
FIELD |
字段声明(包括枚举常量) |
METHOD |
方法 |
PARAMETER |
方法参数 |
CONSTRUCTOR |
构造函数 |
LOCAL_VARIABLE |
局部变量 |
ANNOTATION_TYPE |
注解类型(元注解) |
PACKAGE |
包声明(通过package-info.java 文件) |
TYPE_PARAMETER |
类型参数(Java 8+,用于泛型声明,如<T> ) |
TYPE_USE |
类型使用(Java 8+,可用于任何类型引用,如@NonNull String ) |
MODULE |
模块声明(Java 9+,用于module-info.java 文件) |
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Test {
boolean enabled() default true;
}
public class MyTestClass {
@Test(enabled = false)
public void testMethod() { ... } // 正确使用
}
@Retention
的基本用法
@Retention
是一个元注解(用于注解其他注解的注解),它用于指定被修饰的注解的生命周期,即注解在何时被保留、何时被丢弃。通过@Retention
,可以精确控制注解在编译期、类加载期或运行时的行为。
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME) // 该注解保留至运行时
public @interface MyRuntimeAnnotation {
String value() default "";
}
RetentionPolicy 值 | 描述 | 典型应用场景 |
---|---|---|
SOURCE |
注解仅存在于源代码中,编译时被编译器丢弃,不会包含在 class 文件中。 | 代码检查(如@Override )、代码生成工具(如 Lombok) |
CLASS |
注解在编译时被保留在 class 文件中,但 JVM 运行时会被丢弃。默认值。 | 字节码处理工具(如 AspectJ)、编译时注解处理器 |
RUNTIME |
注解在编译时被保留在 class 文件中,且在 JVM 运行时可通过反射访问。 | 运行时反射(如 JUnit、Spring 框架) |
自定义注解
在 Java 中,自定义注解是一种强大的元编程工具,它允许开发者为代码添加自定义元数据,并在编译时或运行时通过反射机制读取和处理这些信息。下面将详细介绍自定义注解的步骤、应用场景和最佳实践。
使用@interface
关键字定义注解,配合元注解(如@Retention
、@Target
)指定注解的生命周期和使用范围:
import java.lang.annotation.*;
// 元注解:指定注解的生命周期(运行时保留)
@Retention(RetentionPolicy.RUNTIME)
// 元注解:指定注解可用于类、方法和字段
@Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD})
// 元注解:指定注解信息会被包含在JavaDoc中
@Documented
public @interface MyAnnotation {
// 定义注解参数,使用方法名形式,可设置默认值
String value() default ""; // 常用的默认参数名
int priority() default 1; // 优先级参数
String[] tags() default {}; // 数组参数
Class<?> type() default Void.class; // 类类型参数
}
元注解详解
元注解是用于修饰注解的特殊注解,Java 提供了 5 种标准元注解:
@Retention
:指定注解的生命周期RetentionPolicy.SOURCE
:仅存在于源代码中RetentionPolicy.CLASS
:保留到 class 文件(默认)RetentionPolicy.RUNTIME
:保留到运行时,可通过反射访问
@Target
:指定注解的使用范围(如类、方法、字段等)ElementType.TYPE
:类、接口、枚举ElementType.METHOD
:方法ElementType.FIELD
:字段- 其他值:
PARAMETER
、CONSTRUCTOR
、LOCAL_VARIABLE
等
@Documented
:指定注解信息会被包含在 JavaDoc 中@Inherited
:指定子类可以继承父类的注解(仅对类有效)@Repeatable
(Java 8+):允许在同一元素上重复使用同一注解