一. 简介

自从Java 5引入了注释支持以来,此功能就非常流行并且得到了广泛的使用。但是,注释使用的限制之一是不能在同一位置多次声明同一注释。Java 8违反了此规则,并引入了重复注释。它允许相同的注释在声明的位置重复多次。
重复的注释本身应使用@Repeatable注释进行注释。实际上,这不是语言更改,而是更多的编译器技巧,因为该技术的原理保持不变。让我们看一个简单的例子:

例1:您正在编写代码以使用计时器服务,该服务使您可以在给定时间或特定时间表上运行方法,类似于UNIX cron服务。现在,您要设置一个计时器来运行方法doPeriodicCleanup,该方法在一个月的最后一天以及每个星期五的晚上11:00进行。要设置计时器的运行,请创建@Schedule注释并将其两次应用于doPeriodicCleanup方法。第一次使用指定月份的最后一天,第二次使用指定星期五的晚上11点,如以下代码示例所示:

  1. @Schedule(dayOfMonth ="last")
  2. @Schedule(dayOfWeek ="first,hour ="23")
  3. public void doPeriodicCleanup(){...}

例2:前面的示例将注释应用于方法。您可以在使用标准注释的任何地方重复注释。例如,您有一个用于处理未经授权的访问异常的类。您用一个@Alert对经理的注释和对管理员的注释对类进行注释:

  1. @Alertrole =“ Manager”)
  2. @Alertrole =“ Administrator”)
  3. public UnauthorizedAccessException extends SecurityException {...}

二. 实现

1. java8之前

java 8之前也有重复使用注解的解决方案,但可读性不是很好,比如下面的代码:

  1. public @interface Authority {
  2. String role();
  3. }
  4. public @interface Authorities {
  5. Authority[] value();
  6. }
  7. public class RepeatAnnotationUseOldVersion {
  8. @Authorities({@Authority(role="Admin"),@Authority(role="Manager")})
  9. public void doSomeThing(){
  10. }
  11. }

2. java8之后

需要用@Repeatable来声明这是一个重复注解Authority,传入class来指向另一个存储注解Authorities,然后我们使用的时候就按照正常注解使用即可

  1. //y
  2. @Repeatable(Authorities.class)
  3. public @interface Authority {
  4. String role();
  5. }
  6. //储存注解的Authorities
  7. public @interface Authorities {
  8. Authority[] value();
  9. }
  10. public class RepeatAnnotationUseNewVersion {
  11. @Authority(role="Admin")
  12. @Authority(role="Manager")
  13. public void doSomeThing(){ }
  14. }

设计注意事项

设计批注类型时,必须考虑该批注的基数。现在可以使用注释零次,一次,或者如果注释的类型标记为@Repeatable,则可以多次使用。也可以通过使用@Target元注释来限制可以在何处使用注释类型。例如,您可以创建一个只能在方法和字段上使用的可重复注释类型。仔细设计注释类型以确保使用注释的程序员发现它尽可能灵活和强大非常重要。