Java 5 引入註解機制,徹底改變了框架開發與元資料管理方式。本文系統梳理註解的設計動機、核心語法、內建元註解,並通過一個測試框架實例展示實戰應用。
ejb-jar.xml、JavaBean 的 BeanInfo 類,皆可內嵌為註解,減少同步維護錯誤。transient、@Deprecated 早期即為特殊註解形式,Java 5 統一為通用機制。@:@interface MyAnno { ... }。throws。String、Class、enum、註解型別、及其陣列。String author() default "unknown";。| 類型 | 定義範例 | 使用範例 |
|---|---|---|
| 標記註解 | @interface Preliminary {} | @Preliminary class Foo {}(可省略括號) |
| 單元素註解 | @interface Copyright { String value(); } | @Copyright("2024")(省略 value=) |
| 完整註解 | 含多個元素 | @RequestForEnhancement(id=1, synopsis="...") |
@Retention(RetentionPolicy.RUNTIME):保留至運行時,可反射讀取。@Target(ElementType.METHOD):限制作用目標(類、方法、欄位等)。@Documented:納入 Javadoc。@Inherited:允許子類繼承。// 1. 定義 @Test 註解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Test {}
// 2. 被測類
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"); }
}
// 3. 測試執行器
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);
}
}
輸出:
Test public static void Foo.m3() failed: java.lang.RuntimeException: Boom
Test public static void Foo.m7() failed: java.lang.RuntimeException: Crash
Passed: 2, Failed: 2
此框架可輕鬆擴展支援 @Before、@After、參數化測試等進階功能。