177. Java 注释 - 重复注释

177. Java 注释 - 重复注释

Java SE 8 开始,Java 引入了 重复注释repeated annotations)特性,这使得开发人员可以将相同的注释应用于同一个声明或类型使用的多个位置。这在一些场景下非常有用,特别是当需要在代码中对同一方法或类进行多次相同的注释时。

📌 示例场景:设置定时任务

假设正在编写一个应用程序,需要在每月的最后一天和每周五的晚上 11:00 执行清理任务。在没有重复注释的情况下,只能在方法上应用一次注释,但现在,通过重复注释,可以轻松为 doPeriodicCleanup() 方法添加多个定时执行的规则。

示例:使用重复注释设置定时任务
java 复制代码
@Retention(RetentionPolicy.RUNTIME)
@Repeatable(Schedules.class)
public @interface Schedule {
    String dayOfMonth() default "";
    String dayOfWeek() default "";
    String hour() default "";
}
java 复制代码
@Retention(RetentionPolicy.RUNTIME)
public @interface Schedules {
    Schedule[] value();
}
java 复制代码
@Schedule(dayOfMonth="last")  // 每月最后一天执行
@Schedule(dayOfWeek="Fri", hour="23")  // 每周五晚上 11 点执行
public void doPeriodicCleanup() {
    // 执行清理任务的代码
}

在上面的代码中,@Schedule 注解被应用于 doPeriodicCleanup() 方法两次,分别指定了两种不同的时间规则:一个是每月的最后一天,一个是每周五晚上 11 点。这种方式使得代码更清晰易懂,而不必创建多个定时器配置。

📌 示例场景:类级别的多重警报

再举一个例子,假设有一个处理未授权访问的异常类,需要分别为不同角色(如经理和管理员)发送警报。传统方法可能需要为每个角色配置不同的逻辑或注解,但通过重复注释,可以直接为同一个类应用多个注释。

示例:使用重复注释处理不同角色的警报
java 复制代码
@Alert(role="Manager")  // 针对经理的警报
@Alert(role="Administrator")  // 针对管理员的警报
public class UnauthorizedAccessException extends SecurityException {
    // 异常处理代码
}

在这个例子中,@Alert 注解被应用于 UnauthorizedAccessException 类两次,分别为不同角色的警报通知。这使得代码更加简洁且易于维护。

📌 步骤 1:声明可重复注释类型

要使用重复注释,首先需要声明注释类型是可重复的。这是通过使用 @Repeatable 元注解来实现的。@Repeatable 元注解的值是一个容器注解,容器注解是用来存储重复的注解的。

示例:声明可重复注释类型
java 复制代码
import java.lang.annotation.Repeatable;

@Repeatable(Schedules.class)
public @interface Schedule {
    String dayOfMonth() default "first";
    String dayOfWeek() default "Mon";
    int hour() default 12;
}

在这个例子中,@Schedule 注解被标注为 @Repeatable(Schedules.class),其中 Schedules 是用来存储重复 @Schedule 注解的容器注解。

📌 步骤 2:声明容器注释类型

接下来,需要声明一个容器注解类型,它的 value 元素是一个包含注释的数组。这个容器注解类型将作为存储多个重复注释的地方。

示例:声明容器注解
java 复制代码
public @interface Schedules {
    Schedule[] value();
}

在这个例子中,@Schedules 是一个容器注解类型,它包含一个 Schedule 类型的数组。每次应用多个 @Schedule 注解时,它们会被存储在 @Schedules 容器注解中。

📌 获取重复注释

Java 提供了多种方法来检索重复注释。使用反射 API,可以通过以下方式获取容器注释,从而获取所有的重复注释。

  • 获取单个注释AnnotatedElement.getAnnotation(Class) 方法用于获取某个注释类型的第一个注释。
  • 获取多个注释AnnotatedElement.getAnnotationsByType(Class) 方法用于获取容器注释内的所有重复注释。
示例:使用反射获取重复注释
java 复制代码
try {
    // 获取当前类的Class对象
    Class<?> myClass = Demo.class;

    // 获取doPeriodicTask方法
    Method method = myClass.getDeclaredMethod("doPeriodicTask");

    // 获取Schedules注解
    Schedules schedules = method.getAnnotation(Schedules.class);
    if (schedules != null) {
        for (Schedule schedule : schedules.value()) {
            System.out.println("Day of Month: " + schedule.dayOfMonth());
        }
    }

    // 也可以直接获取Schedule注解(如果只有一个)
    Schedule[] scheduleArray = method.getAnnotationsByType(Schedule.class);
    for (Schedule schedule : scheduleArray) {
        System.out.println("Schedule - Day of Month: " + schedule.dayOfMonth() +
                           ", Day of Week: " + schedule.dayOfWeek() +
                           ", Hour: " + schedule.hour());
    }

} catch (NoSuchMethodException e) {
    e.printStackTrace();
}

在这个例子中,通过反射获取 @Schedules 容器注解,然后遍历其中存储的所有 @Schedule 注解,打印出每个注解的相关信息。

📌 设计注意事项

在设计可重复的注释时,有几个重要的注意事项:

  1. 注释的基数 :注释可以应用零次、一次或多次。如果注释类型被标记为 @Repeatable,则可以多次使用该注释。
  2. 注释的适用位置 :通过 @Target 元注解,可以限制注释的应用位置。例如,可以创建只能用于方法和字段的可重复注释类型。
  3. 兼容性 :使用 @Repeatable 注解类型时,确保遵循 Java 的兼容性规则。由于 @Repeatable 注解是容器注解,所以编译器会自动生成容器注解,并将多个相同的注释存储在容器中。

📌 总结

  • 重复注释 :从 Java SE 8 开始,可以将相同的注释应用于同一声明或类型的多个位置。这通过使用 @Repeatable 元注解实现。
  • 应用场景:重复注释在需要为同一方法或类应用多个相同类型的注释时非常有用。例如,定时任务、角色警报等。
  • 设计和使用 :设计可重复的注释时,考虑注释的应用基数以及注释类型的适用位置。使用 @Repeatable 元注解来定义可以重复应用的注释类型。

重复注释极大增强了 Java 代码的灵活性和可维护性,尤其是在处理多个类似的配置或规则时。

相关推荐
一孤程1 小时前
Airtest自动化测试第五篇:小程序与Web测试——跨平台自动化全覆盖
前端·自动化测试·小程序·自动化·测试·airtest
IT_陈寒1 小时前
SpringBoot自动配置不是你以为的那样的智能
前端·人工智能·后端
yume_sibai2 小时前
大屏数据可视化 - 边框红绿呼吸灯实现详解
前端·信息可视化·typescript
Hyyy3 小时前
很多Desktop都在上的Computer Use是什么
前端·llm
慢功夫3 小时前
开篇:VS Code 为什么不是一个普通 React App
前端·visual studio code
你挚爱的强哥3 小时前
Vue2 实现 1.5s 十连击监听(连续点击若干次),封装通用可复用点击检测工具,不用 data!Vue 封装通用连击监听方法,支持自定义时长与点击次数
前端·javascript·vue.js
程序员张33 小时前
SpringBoot集成BCrypt密码加密库
java·spring boot·后端
CaffeinePro3 小时前
FastAPI数据库集成SQLAlchemy异步ORM全方案
后端·fastapi
小旭Coding3 小时前
凌晨告警轰炸!Go 服务协程只增不减,内存持续暴涨直至 OOM
后端
半个落月3 小时前
用 LangChain.js 手写一个能读写文件和执行命令的 Mini Cursor
javascript·人工智能·后端