当前位置: 首页 > article >正文

Java 注解详解:RetentionPolicy 与 ElementType

文章目录

  • 1. RetentionPolicy:注解的生命周期
    • RetentionPolicy 的详细说明
      • SOURCE 示例
      • CLASS 示例
      • RUNTIME 示例
  • 2. ElementType:注解的应用范围
    • ElementType 的详细说明
    • ElementType 示例
      • 用于类
      • 用于方法
      • 用于局部变量
  • 3. RetentionPolicy 与 ElementType 的结合应用
    • 案例:开发一个运行时注解
      • 实现步骤
      • 运行结果
  • 4. 总结与扩展
    • 总结
    • 扩展

Java 的注解机制是代码元数据的一种强大表达形式,它能够在编译期或运行期为程序添加信息,并通过工具或框架加以利用。其中, RetentionPolicyElementType 是 Java 注解体系中的两个核心组成部分,决定了注解的生命周期和适用范围。

本文将深入解读 RetentionPolicyElementType 的作用及其使用场景,帮助开发者全面掌握注解的基础与高级应用。


1. RetentionPolicy:注解的生命周期

RetentionPolicy 定义了注解的保留策略,决定了注解在源代码、字节码或运行时的可用性。以下是 RetentionPolicy 的源码定义:

package java.lang.annotation;

public enum RetentionPolicy {
    /** 注解只保留在源代码中,编译后将被丢弃。 */
    SOURCE,

    /** 注解保留在字节码中,但运行时不可见(默认策略)。 */
    CLASS,

    /** 注解保留在字节码中,且运行时可通过反射获取。 */
    RUNTIME
}

RetentionPolicy 的详细说明

描述
SOURCE注解只存在于源代码中,编译后会被丢弃。适用于编译期工具,例如代码生成器。
CLASS注解会记录到字节码中,但 JVM 在运行时无法访问。默认策略,适用于不需要运行时处理的场景。
RUNTIME注解会记录到字节码中,且在运行时通过反射可见。适用于需要运行时动态处理的注解,例如 Spring 框架。

SOURCE 示例

用于生成代码或编译时检查:

@Retention(RetentionPolicy.SOURCE)
@interface SourceAnnotation {}

CLASS 示例

默认策略,多用于标记类信息:

@Retention(RetentionPolicy.CLASS)
@interface ClassAnnotation {}

RUNTIME 示例

常见于依赖运行时反射的框架:

@Retention(RetentionPolicy.RUNTIME)
@interface RuntimeAnnotation {}

2. ElementType:注解的应用范围

ElementType 定义了注解可以应用的目标类型,例如类、方法、字段等。其源码如下:

package java.lang.annotation;

public enum ElementType {
    TYPE,             // 类、接口(包括注解类型)或枚举声明
    FIELD,            // 字段声明(包括枚举常量)
    METHOD,           // 方法声明
    PARAMETER,        // 方法参数声明
    CONSTRUCTOR,      // 构造函数声明
    LOCAL_VARIABLE,   // 局部变量声明
    ANNOTATION_TYPE,  // 注解类型声明
    PACKAGE,          // 包声明
    TYPE_PARAMETER,   // 类型参数声明
    TYPE_USE          // 类型使用
}

ElementType 的详细说明

描述
TYPE用于类、接口、枚举的声明。
FIELD用于类的成员变量或枚举常量。
METHOD用于类或接口的方法。
PARAMETER用于方法的参数。
CONSTRUCTOR用于类的构造函数。
LOCAL_VARIABLE用于局部变量。
ANNOTATION_TYPE用于注解的定义。
PACKAGE用于指定包。
TYPE_PARAMETER用于泛型参数(JDK 1.8+)。
TYPE_USE用于任何类型的使用(JDK 1.8+),包括泛型、数组、类型转换等。

ElementType 示例

用于类

@Target(ElementType.TYPE)
@interface TypeAnnotation {}

用于方法

@Target(ElementType.METHOD)
@interface MethodAnnotation {}

用于局部变量

@Target(ElementType.LOCAL_VARIABLE)
@interface LocalVariableAnnotation {}

3. RetentionPolicy 与 ElementType 的结合应用

通过结合 RetentionPolicyElementType,可以精准控制注解的生命周期和适用范围。开发者可以根据不同需求选择合适的生命周期策略和应用范围,从而提高注解的灵活性和可扩展性。

案例:开发一个运行时注解

需求:创建一个运行时注解,用于标记方法参数,并在运行时通过反射获取注解信息。

实现步骤

  1. 定义注解:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface ParamAnnotation {
    String value();
}
  1. 使用注解:
public class Example {
    public void sayHello(@ParamAnnotation("name") String name) {
        System.out.println("Hello, " + name);
    }
}
  1. 通过反射获取注解信息:
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

public class AnnotationDemo {
    public static void main(String[] args) throws Exception {
        Method method = Example.class.getMethod("sayHello", String.class);
        Parameter[] parameters = method.getParameters();

        for (Parameter parameter : parameters) {
            if (parameter.isAnnotationPresent(ParamAnnotation.class)) {
                ParamAnnotation annotation = parameter.getAnnotation(ParamAnnotation.class);
                System.out.println("Parameter: " + parameter.getName() + ", Value: " + annotation.value());
            }
        }
    }
}

运行结果

Parameter: arg0, Value: name

4. 总结与扩展

总结

  • RetentionPolicy 决定了注解的生命周期,常用策略为 RUNTIME,适用于动态处理。
  • ElementType 决定了注解的适用范围,能够精确定位注解目标。
  • 两者结合为注解的使用提供了更多灵活性,能够满足复杂的业务需求。

扩展

  • 组合注解:结合多个注解实现复杂功能,例如 Spring 的组合注解(@RestController)。
  • 元注解:通过 @Retention@Target 定义新的注解行为。
  • 工具化应用:使用注解生成代码(如 Lombok),或结合 AOP 实现切面逻辑。

通过对 RetentionPolicyElementType 的深入理解与灵活应用,开发者可以更高效地开发框架、工具和业务逻辑,充分发挥注解机制的优势。


http://www.kler.cn/a/473441.html

相关文章:

  • C++ 泛型编程:动态数据类模版类内定义、类外实现
  • 【搜索】【推荐】大 PK
  • maven如何从外部导包
  • Redis 数据库源码分析
  • 嵌入式技术之Linux(Ubuntu) 一
  • 【VUE+ElementUI】通过接口下载blob流文件设置全局Loading加载进度
  • [Git] git pull --rebase / git rebase origin/master
  • 用VS C#构建Windows服务【纯操作版,附带项目地址】
  • python_excel列表单元格字符合并、填充、复制操作
  • 基于64QAM的载波同步和定时同步性能仿真,包括Costas环和gardner环
  • docker一键安装脚本(docker安装)
  • 基于 Python 自动化接口测试(踩坑与实践)
  • 【ROS2】从零开始使用URDF构建机器人
  • java之Collection
  • USB 驱动开发 --- Gadget 设备连接 Windows 免驱
  • 基于物联网疫苗冷链物流监测系统设计
  • go语言学习 笔记 1(变量,语法,数据类型)
  • 【.NET】Kafka消息队列介绍,使用Confluent.Kafka集成Kafka消息队列
  • 如何使用脚手架工具开始,快速搭建一个 Express 项目的基础架构
  • Online Judge PTA 最大公约数与最小公倍数
  • 网络安全 基础入门-概念名词
  • 文件读写到SQLite数据库的方法
  • C++编程等级认证学习计划day2-1
  • 万界星空科技质量管理QMS系统具体功能介绍
  • AT6668-6N-22:BDS定位SOC芯片,常用在车载系统
  • TensorRT-LLM中的MoE并行推理