| 註解 | 用途 | 範例 |
@Override | 檢查是否正確覆寫父類方法 | 編譯期報錯防止拼錯方法名 |
@SuppressWarnings | 抑制特定編譯警告 | @SuppressWarnings("unchecked") |
@Deprecated | 標記 API 已過時 | IDE 會劃線提醒 |
自訂註解四步驟
- 宣告:
public @interface MyAnn { }
- 指定保留策略:
@Retention(RetentionPolicy.RUNTIME)
- 指定作用目標:
@Target({ElementType.TYPE, ElementType.METHOD})
- 定義屬性:
String value() default "";
完整範例
import java.lang.annotation.*;
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface MyAnnotation {
String value(); // 必填
String color() default "red"; // 可選,有預設值
WeekDay week() default WeekDay.MON; // 列舉型別
int[] ids() default {1,2,3}; // 陣列型別
Class> clazz() default String.class; // Class 型別
OtherAnnotation ann() default @OtherAnnotation("x"); // 註解巢狀
}
enum WeekDay { MON, TUE, WED }
@Retention(RetentionPolicy.RUNTIME)
@interface OtherAnnotation { String value(); }
// 使用
@MyAnnotation(value="demo", color="blue", week=WeekDay.WED, ids={5}, clazz=Integer.class)
public class Demo {
@MyAnnotation("method-value")
public void test() {}
}
反射讀取註解
// 類別層級
if (Demo.class.isAnnotationPresent(MyAnnotation.class)) {
MyAnnotation ann = Demo.class.getAnnotation(MyAnnotation.class);
System.out.println(ann.value()); // demo
System.out.println(ann.color()); // blue
System.out.println(ann.week()); // WED
System.out.println(ann.ids().length); // 1
System.out.println(ann.clazz()); // class java.lang.Integer
}
// 方法層級
Method m = Demo.class.getMethod("test");
MyAnnotation mAnn = m.getAnnotation(MyAnnotation.class);
System.out.println(mAnn.value()); // method-value
保留策略對照
| 策略 | 存活範圍 | 適用場景 |
SOURCE | 僅原始碼,編譯捨棄 | @Override, @SuppressWarnings |
CLASS | .class 檔案,JVM 不載入 | 預設值,框架掃描 class 檔 |
RUNTIME | JVM 載入,反射可讀 | 執行期驗證、AOP、配置綁定 |
目標類型
@Target({
ElementType.TYPE, // 類別/介面/列舉
ElementType.METHOD, // 方法
ElementType.FIELD, // 欄位
ElementType.PARAMETER, // 參數
ElementType.CONSTRUCTOR, // 建構子
ElementType.LOCAL_VARIABLE,
ElementType.ANNOTATION_TYPE,
ElementType.PACKAGE,
ElementType.TYPE_PARAMETER, // Java 8+
ElementType.TYPE_USE // Java 8+
})
最佳實務
- 業務註解務必加
@Retention(RUNTIME),否則反射讀不到。
- 屬性命名慣用
value() 作為單一主要屬性,使用時可省略屬性名:@Ann("x")。
- 陣列屬性單值時可省略大括號:
ids=5 等同 ids={5}。
- 配合
AnnotationProcessor (APT) 可在編譯期產生程式碼/檢查規範。
- 上一篇文章: MSXML2.XMLHTTP vs ServerXMLHTTP:快取機制差異與選型指南
- 下一篇文章: Java Socket 通訊入門:簡易 Client/Server 完整範例與多執行緒處理
Copyright ©
程式碼之家 All Rights Reserved