Java 8可重复的自定义注解

17

我知道Java中的基本注解,比如@Override等。

Annotations are only metadata and they do not contain any business logic.

我正在阅读Oracle 文档 页面上的重复注解,以了解 Java 8 的新功能。

例如,您正在编写代码以使用“定时器服务,使您能够在给定时间或特定计划上运行方法,类似于 UNIX cron 服务”。现在您想要设置一个计时器来运行一个名为doPeriodicCleanup的方法,在每个月的最后一天以及每个星期五晚上11:00运行。要设置计时器运行,请创建一个@Schedule注解,并将其两次应用于 doPeriodicCleanup 方法。

@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
public void doPeriodicCleanup() { ... }

声明可重复注释类型

注释类型必须标记为@Repeatable元注释。以下示例定义了一个自定义的@Schedule可重复注释类型:

import java.lang.annotation.Repeatable;

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

声明包含注解类型

包含注解类型必须具有一个数组类型的值元素。该数组类型的组件类型必须是可重复注解类型。Schedules包含注解类型的声明如下:

public @interface Schedules {
    Schedule[] value();
}

我不理解@Schedules注释的使用和用法。 它如何在下面的方法中工作?

public void doPeriodicCleanup() { ... }

提前感谢。


为什么需要重复注释?在我看来,您可以在单个实例上拥有所有属性,然后从存在和省略的属性中确定意图。显然,某些属性组合是无效的,但您已经面临了这种情况。 - Jim Garrison
4
我只是在尝试理解Oracle文档页面。这个例子是从那里引用的。 - Ravindra babu
1个回答

26

在Java 8之前,给定的注解只能在方法(或类、字段等)上设置一次。因此,如果您想在单个方法上设置两个不同的计划,您必须定义一个“包装”注解,例如Schedules,其中包含一个Schedule注解数组。

因此,开发人员需要进行如下操作:

@Schedules(value = {
    @Schedule(dayOfMonth="last"),
    @Schedule(dayOfWeek="Fri", hour="23")
})

这段文字不太易读,而且 Schedules 注释除了包含多个 Schedule 注释以外没有任何作用。

为了减少样板代码,但保持注释 API 不变,现在允许直接在方法上进行注解:

@Schedule(dayOfMonth="last"),
@Schedule(dayOfWeek="Fri", hour="23")

通过将Schedule声明为可重复,并指定其"包装"注解,可以实现相同的效果,但这只是语法糖:方法在运行时被视为带有一个Schedules注解,其中包含两个Schedule。编译器将第二段代码转换为第一段代码。


谢谢提供信息。我只有一个小问题。现在 @Repeatable 应该放在哪里? - Ravindra babu
1
在必须可重复的注释上:Schedule。就像教程所解释的那样。 - JB Nizet
糟糕,这是我自己的愚蠢错误。 - Ravindra babu
这是一些语法糖加上Reflections API中的一些辅助方法,以便更轻松地从类型或成员中获取这样的重复注释。由于重复注释是容器注释的语法糖,因此您可以使用这些新方法来提取容器注释(如果元素注释具有适当的“@Repeatable”注释)。 - Holger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接