首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 8 重複註解:@Repeatable 元註解讓同一註解可多次標註

     編輯:Java 相關知識

從容器註解模擬到原生支援:註解 API 的小進化、大便利

Java 8 前若需在同一位置多次使用同一註解,必須定義「容器註解」包裝陣列:@Authorities({@Authority("Admin"), @Authority("Manager")})。Java 8 引入 @Repeatable 元註解,配合容器註解,實現語法層面的原生重複:@Authority("Admin") @Authority("Manager")。編譯器自動合成容器註解,反射 API 提供 getAnnotationsByType() 直接獲取重複註解陣列。

Java 7 寫法(容器模擬)

@Retention(RUNTIME) @Target({TYPE, METHOD, FIELD})
public @interface Authorities { Authority[] value(); }

@Retention(RUNTIME) @Target({TYPE, METHOD, FIELD})
public @interface Authority { String role(); }

// 使用
@Authorities({@Authority("Admin"), @Authority("Manager")})
public void doSomething() {}

Java 8 寫法(原生重複)

@Retention(RUNTIME) @Target({TYPE, METHOD, FIELD})
@Repeatable(Authorities.class) // 指向容器註解
public @interface Authority { String role(); }

// 容器註解必須存在,value() 為重複註解陣列
@Retention(RUNTIME) @Target({TYPE, METHOD, FIELD})
public @interface Authorities { Authority[] value(); }

// 使用:直接重複標註
@Authority("Admin")
@Authority("Manager")
public void doSomething() {}

// 反射獲取(Java 8 新增)
Authority[] authorities = method.getAnnotationsByType(Authority.class);
// 或獲取容器
Authorities container = method.getAnnotation(Authorities.class);

關鍵規則

  1. @Repeatable 的值必須是容器註解類型(Authorities.class)。
  2. 容器註解必須有一個 value() 方法,型別為重複註解的陣列(Authority[])。
  3. 重複註解與容器註解的 @Retention、@Target 必須兼容(通常相同)。
  4. 同一位置可重複 0~N 次;0 時反射獲取空陣列,不會有容器註解。

反射 API 差異

方法Java 7 行為Java 8+ 行為
getAnnotation(Authority.class)返回單個(若用容器則返回容器)返回第一個重複註解(為兼容性)
getAnnotationsByType(Authority.class)不存在返回所有重複註解陣列(含容器展開)
getDeclaredAnnotationsByType()不存在同理,不繼承父類註解
getAnnotation(Authorities.class)返回容器返回合成的容器註解

適用場景

  • 多權限、多角色、多標籤、多驗證規則等「同類語義、多值」場景。
  • 框架開發:Spring @Scheduled、@Cacheable、@EventListener 均已支援重複。
  • 代碼生成/註解處理器:RoundEnvironment.getElementsAnnotatedWith() 可正確識別重複註解。

避坑指南

  • 容器註解必須手動定義,編譯器不會自動生成類文件。
  • 若同時存在重複註解和容器註解(手寫),編譯器報錯:Duplicate annotation。
  • 繼承場景:@Inherited 僅作用於容器註解,重複註解本身不繼承。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved