Annotation (標註) 自 Java 5.0 引入,提供將中繼資料與程式元素 (類別、方法、欄位等) 關聯的標準機制。本文從基本觀念、定義語法、內建類型、自訂範例到進階應用方向,完整勾勒 Annotation 入門脈絡。
BeanInfo、EJB 需部署描述符,Annotation 可將資訊內嵌原始碼,同步維護、減少錯誤。Java 5.0 前已有臨機機制 (transient、@deprecated javadoc tag)。5.0 提供正式功能:定義/使用自訂 Annotation 類型、讀取 API (java.lang.reflect)、apt 處理工具。Annotation 不直接影響程式語義,但工具/程式庫可讀取並反向影響行為。來源可為原始碼、Class 檔或執行期反射。
使用 @interface 關鍵字,方法宣告對應成員,回傳型別限於基本型別、String、Class、Enum、Annotation 及其陣列,可指定預設值。
public @interface RequestForEnhancement {
int id();
String synopsis();
String engineer() default "[unassigned]";
String date() default "[unimplemented]";
}
格式:@AnnotationType(member=value, ...)。成員值必須為編譯期常數。
@RequestForEnhancement(
id = 2868724,
synopsis = "Enable time-travel",
engineer = "Mr. Peabody",
date = "4/1/3007"
)
public static void travelThroughTime(Date destination) { ... }
@Preliminary。value=,如 @Copyright("2002 Yoyodyne")。@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test { }
@Retention(RUNTIME) 保留至執行期可反射讀取;@Target(METHOD) 限定只能修飾方法。
public class Foo {
@Test public static void m1() { }
public static void m2() { }
@Test public static void m3() { throw new RuntimeException("Boom"); }
@Test public static void m5() { }
@Test public static void m7() { throw new RuntimeException("Crash"); }
}
public class RunTests {
public static void main(String[] args) throws Exception {
int passed = 0, failed = 0;
for (Method m : Class.forName(args[0]).getMethods()) {
if (m.isAnnotationPresent(Test.class)) {
try { m.invoke(null); passed++; }
catch (Throwable ex) { System.out.printf("Test %s failed: %s%n", m, ex.getCause()); failed++; }
}
}
System.out.printf("Passed: %d, Failed %d%n", passed, failed);
}
}
執行結果:Passed: 2, Failed 2。
@Deprecated:標示過時 API,編譯器警告。@Override:斷言覆寫父類方法,拼錯方法名會編譯錯誤。@SuppressWarnings:選擇性關閉編譯器警告 (如 unchecked、fallthrough)。開發者定義類型,配合反射/APT 實現特定功能 (如方法測試、程式碼產生)。
如 Hibernate 3 使用 Annotation 取代 XDoclet 產生對應檔。
Annotation 保留策略分 執行期 (RUNTIME) 與 編譯期 (SOURCE/CLASS)。本文著重執行期反射應用;編譯期處理需使用 apt (Annotation Processing Tool),將於進階篇探討 (如自訂 Annotation 產生 JavaBean 對應 XML)。