J2SE 5.0 在 java.lang.annotation 套件定義四個元註解,專門用於修飾其他註解類型的定義,控制其使用規則與生命週期:
@Target({ElementType.METHOD, ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface TODO { int priority() default 0; }
ElementType 列舉值:
| 常數 | 適用位置 |
|---|---|
| TYPE | 類別、介面、枚舉、註解類型 |
| FIELD | 欄位(包含 enum 常數) |
| METHOD | 方法 |
| PARAMETER | 方法參數 |
| CONSTRUCTOR | 建構子 |
| LOCAL_VARIABLE | 區域變數 |
| ANNOTATION_TYPE | 註解類型定義 |
| PACKAGE | 套件宣告 |
| TYPE_PARAMETER (Java 8+) | 型別參數 |
| TYPE_USE (Java 8+) | 型別使用處 |
編譯器強制檢查:若 @TODO 限定 METHOD,標註在欄位上將編譯錯誤:
public class MyCalculator {
@TODO boolean isReady; // 錯誤:@TODO not applicable to field
@TODO public void calculate() { } // 正確
}

@Retention(RetentionPolicy.RUNTIME) // 關鍵:執行期可見
public @interface TODO { ... }
| 策略 | 保留範圍 | 適用場景 |
|---|---|---|
SOURCE | 僅原始碼,編譯器捨棄,.class 無痕跡 | 編譯期檢查、代碼生成(如 @Override、@SuppressWarnings) |
CLASS | .class 保留,JVM 載入時不解析(預設值) | 位元組碼工具分析、文件生成 |
RUNTIME | .class 保留,JVM 載入解析,反射可讀 | 執行期掃描、框架裝配、驗證、序列化 |
鐵律:需執行期反射讀取的註解,必須標註 @Retention(RUNTIME),否則 isAnnotationPresent() 永回傳 false。
@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface APIChange { String since(); String reason(); }
被 @Documented 修飾的註解,javadoc 工具會將其包含在生成的 API 文件中,成為公開契約一部分。適用於對外發布的 API 級註解(如 @Deprecated 本身即標註 @Documented)。
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface Auditable { }
作用機制:當註解標註在類別上且帶有 @Inherited 時,該類別的子類別在反射查詢 getAnnotations()(非 getDeclaredAnnotations())時,會自動包含父類別的該註解。
// 完整定義:方法級、執行期可見、納入文件、可繼承
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Transactional {
Propagation propagation() default Propagation.REQUIRED;
Isolation isolation() default Isolation.READ_COMMITTED;
int timeout() default -1;
boolean readOnly() default false;
}
@Target( 後 Ctrl+Space 列出所有 ElementType。@Target(METHOD) 的註解用於欄位 → 紅線報錯。RUNTIME 註解 → 黃線警告「Annotation not retained at runtime」。@Documented 註解顯示「Included in Javadoc」。四大元註解構成註解類型的憲法級配置:@Target 定邊界、@Retention 定壽命、@Documented 定曝光、@Inherited 定傳遞。正確組合它們,是設計高質量、工具友善、語義精確的註解類型的前提。