JDK 內建三大註解回顧
@Override:標記覆寫父類方法,編譯器檢查簽名一致性。
@Deprecated:標記過時 API,編譯警告。
@SuppressWarnings:壓制特定編譯警告。
四大元註解(Meta-Annotations)
| 元註解 | 作用 | 關鍵取值 |
@Target | 限定註解可用位置 | ElementType:TYPE、FIELD、METHOD、PARAMETER、CONSTRUCTOR、LOCAL_VARIABLE、ANNOTATION_TYPE、PACKAGE |
@Retention | 定義生命週期 | RetentionPolicy:SOURCE(源碼)、CLASS(預設、字節碼)、RUNTIME(運行時載入 JVM) |
@Documented | 納入 Javadoc 生成文檔 | 無參數 |
@Inherited | 允許子類繼承父類註解 | 僅對 TYPE 有效 |
自定義 Annotation 語法規範
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Description {
String value(); // 單屬性慣命名為 value()
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Name {
String originate();
String community();
}
- 以
@interface 定義,自動繼承 java.lang.annotation.Annotation。
- 屬性只能用
public 或預設權限;型別限於 8 大基本型 + String + Enum + Class + Annotation + 其陣列。
- 單屬性建議命名
value(),使用時可省略屬性名:@Description("文字")。
使用範例
@Description("Javaeye,做最棒的軟件開發交流社區")
public class JavaEyer {
@Name(originate="創始人:robbin", community="JavaEye")
public String getName() { return null; }
@Name(originate="創始人:江南白衣", community="springside")
public String getName2() { return "借用兩位的id一用"; }
}
反射運行時提取
Class> clazz = Class.forName("lighter.javaeye.com.JavaEyer");
// 類級註解
if (clazz.isAnnotationPresent(Description.class)) {
Description d = clazz.getAnnotation(Description.class);
System.out.println("描述:" + d.value());
}
// 方法級註解
for (Method m : clazz.getMethods()) {
if (m.isAnnotationPresent(Name.class)) {
Name n = m.getAnnotation(Name.class);
System.out.println(n.originate() + " | " + n.community());
}
}
輸出結果
描述:Javaeye,做最棒的軟件開發交流社區
-----------------
創始人:robbin | JavaEye
創始人:江南白衣 | springside
應用場景
- 框架配置(替代 XML)
- 代碼生成、編譯期檢查(Lombok、MapStruct)
- 測試標記、事務邊界、權限控制等切面編程切點