> For the complete documentation index, see [llms.txt](https://eric3wade.gitbook.io/java/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://eric3wade.gitbook.io/java/learning-the-java-language/annotations/repeating-annotations.md). # Repeating Annotations å¨ä¸äºåºæ¯ä¸ä½ æ³è¦å¨å£°ææè ç±»å使ç¨ä¸æ·»å ä¸äºç¸å ³ç注解ã`Java SE 8 release`䏿ä¾äº`repeating annotations`å®ç°è¿ä¸ªåè½ã ä¾å¦ï¼ä½ æ³ä½¿ç¨å®æ¶æå¡ç¼å代ç 使å¾å¨æå®æ¶é´æè æ¯æç¹å®è®¡åè¿è¡ä¸ä¸ªå½æ°ï¼ç±»ä¼¼äº`UNIX`ä¸ç`cron`æå¡ãç°å¨ä½ æ³è®¾ç½®ä¸ä¸ªå®æ¶å¨å»è¿è¡å½æ°`doPeriodicCleanup`ï¼è¯¥å®æ¶å¨å¨æ¯ä¸ªæçæåä¸å¤©åæ¯ä¸ªææäºæä¸11ç¹æ´å¯å¨ã为äºå®ç°å®æ¶å¨ï¼å建ä¸ä¸ªå为`@Schedule`çæ³¨è§£ï¼å¹¶å¨`doPeriodicCleanup`彿°ä¸ä½¿ç¨ä¸¤æ¬¡ãç¬¬ä¸æ¬¡æä»¬æå®æ¯ä¸ªæçæåä¸å¤©ï¼ç¬¬äºæ¬¡æä»¬æå®ææäºæä¸11ç¹æ´ï¼å ·ä½ä»£ç å¦ä¸æç¤ºï¼ ```java @Schedule(dayOfMonth="last") @Schedule(dayOfWeek="Fri", hour="23") public void doPeriodicCleanup() { ... } ``` è¿ä¸ªä¾åå¨å½æ°ä¸åºç¨æ³¨è§£ãä½ å¯ä»¥ä½¿ç¨æ åæ³¨è§£çææå°æ¹é夿³¨è§£ãä¾å¦ï¼ä½ æä¸ä¸ªå¤çæªææè®¿å¼å¸¸çç±»ï¼ãä½ å¨ç±»ä¸ä¸º`manager`åå ¶ä»`admin`æ·»å ä¸ä¸ª`@Alert`æ³¨è§£ï¼ ```java @Alert(role="Manager") @Alert(role="Administrator") public class UnauthorizedAccessException extends SecurityException { ... } ``` ç±äºå ¼å®¹çåå ï¼é夿³¨è§£è¢«ä¿åç±Javaç¼è¯å¨èªå¨çæç`container annotation`ä¸ã为äºè®©ç¼è¯å¨å®ç°ä¸è¿°åè½ï¼å¨ä½ 代ç ä¸éè¦ä¸¤ä¸ªå£°æã ## Step 1: Declare a Repeatable Annotation Type 注解类åå¿ é¡»è¢«`@Repeatable`å æ³¨è§£æ è®°ï¼ä¸é¢è¿ä¸ªä¾åå®ä¹äºä¸ä¸ªå为`@Schedule`çå¯é夿³¨è§£ï¼ ```java import java.lang.annotation.Repeatable; @Repeatable(Schedules.class) public @interface Schedule { String dayOfMonth() default "first"; String dayOfWeek() default "Mon"; int hour() default 12; } ``` `@Repeatable`å æ³¨è§£æ¬å·éé¢çå¼ï¼å°±æ¯Javaç¼è¯å¨ç¨æ¥çæå¹¶ä¿åé夿³¨è§£ç`container annotation`ï¼å®¹å¨æ³¨è§£ï¼çç±»åãè¿ä¸ªä¾åä¸ï¼å®¹å¨æ³¨è§£çç±»åæ¯`Schedules`ï¼ä¹å°±æ¯è¯´éå¤ç`@Schedule`注解ä¿åå¨ä¸ä¸ª`@Schedules`注解ä¸ã å°ç¸åçæªå£°æå¯éå¤ç注解åºç¨å¨åä¸ä¸ªå£°æä¸ä¼å¯¼è´ç¼è¯æ¶æ¥éã ## Step 2: Declare the Containing Annotation Type 容卿³¨è§£ç±»åå¿ é¡»å å«ä¸ä¸ªæ°ç»ç±»åç`value`å ç´ ãæ°ç»ä¸å ç´ çç±»åå¿ é¡»æ¯å¯é夿³¨è§£ç±»åãå为`Schedules`ç容卿³¨è§£å£°æå¦ä¸ï¼ ```java public @interface Schedules { Schedule[] value(); } ``` **Retrieving Annotations** `Reflection API`æä¾äºä¸äºå½æ°ç¨æ¥è·å注解ãæäºå½æ°è¿ååä¸ªæ³¨è§£ï¼æ¯å¦[ AnnotatedElement.getAnnotation(Class)](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AnnotatedElement.html#getAnnotation-java.lang.Class-)ï¼å¦æåå¨æè¯·æ±ç±»åçä¸ä¸ªæ³¨éï¼å®ä»¬ä» è¿åå个注éï¼å¦æåå¨ä¸ä¸ªä»¥ä¸ç注解ï¼ä½ å¯ä»¥å éè¿ä½¿ç¨å®ä»¬ç容卿³¨è§£æ¥è·åå®ä»¬ãéè¿è¿æ ·ï¼ç¡®ä¿é产代ç è½æ£å¸¸è¿è¡ãJava SE 8ä¸çå ¶ä»å½æ°å¯ä»¥æ«æå®¹å¨æ³¨è§£ä½¿å¾ä¸æ¬¡æ¾åå¤ä¸ªæ³¨è§£ï¼æ¯å¦[AnnotatedElement.getAnnotationsByType(Class)](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AnnotatedElement.html#getAnnotationsByType-java.lang.Class-)ãé 读[AnnotatedElement](https://docs.oracle.com/javase/8/docs/api/java/lang/reflect/AnnotatedElement.html)çè§èè·åè·å¤ä¿¡æ¯ã **Design Considerations** å½è®¾è®¡ä¸ä¸ªæ³¨è§£ç±»åæ¶ï¼ä½ å¿ é¡»èè该类åçæ³¨è§£`cardinality`ï¼åºæ°ï¼ãç°å¨å¯ä»¥ä¸ä½¿ç¨æ³¨è§£æè 使ç¨ä¸æ¬¡ï¼å¦ææ³¨è§£çç±»å被æ 记为`@Repeatable`å¯ä»¥ä½¿ç¨å¤æ¬¡ãå¯ä»¥éè¿ä½¿ç¨`@Target`æ¥éå¶ä½¿ç¨ä¸ä¸ªæ³¨è§£çå°ç¹ãä¾å¦ä½ å¯ä»¥å建ä¸ä¸ªåªè½ç¨å¨å½æ°å屿§ä¸çå¯é夿³¨è§£ã认ççè®¾è®¡ä½ çæ³¨è§£ç±»åæ¯å¾éè¦çï¼è¿æ ·å¯ä»¥ç¡®ä¿å¼åå¨ä½¿ç¨åç°å®æ¢çµæ´»æå¼ºå¤§