Annotation (註解) 是 JDK 1.5 引入的元數據機制,廣泛應用於 Spring、Hibernate 等框架。本文系統講解註解原理、四大元註解、三大內建註解、自定義註解規範與反射解析實戰。
註解不同於註釋:註解可被編譯工具/解析工具處理,註釋僅源碼保留。自定義註解必須用 @interface (隱含繼承 java.lang.annotation.Annotation)。
| 元註解 | 作用 | 關鍵屬性 |
|---|---|---|
| @Documented | 標記的元素會被 javadoc 文檔化 | 無 |
| @Inherited | 註解可被子類自動繼承查找 | 無 |
| @Retention | 指定保留策略 | value(): RetentionPolicy |
| @Target | 限制適用程序元素類型 | value(): ElementType[] |
SOURCE:僅源文件,編譯捨棄CLASS:源文件 + Class 字節碼,運行時 VM 不保留 (預設)RUNTIME:源文件 + Class + 運行時 VM 保留,可反射讀取| 註解 | Target | Retention | 用途 |
|---|---|---|---|
| @Override | METHOD | SOURCE | 檢查是否正確覆寫父類方法 |
| @Deprecated | 除 ANNOTATION_TYPE 外所有 | RUNTIME | 標記不建議使用,javadoc 建議說明替代方案 |
| @SuppressWarnings | 除 ANNOTATION_TYPE、PACKAGE 外所有 | SOURCE | 壓制編譯器警告,value() 接受字串陣列 |
deprecation、unchecked、fallthrough、path、serial、finally、all@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
public @interface AuthorAnno {
String name(); // 必填
String website() default "gityuan.com"; // 選填,有預設值
int revision() default 1;
}
public class AnnotationDemo {
@AuthorAnno(name="yuanhh", website="gityuan.com", revision=1)
public static void main(String[] args) { System.out.println("I am main"); }
@SuppressWarnings({"unchecked", "deprecation"})
@AuthorAnno(name="yuanhh", revision=2)
public void demo() { System.out.println("I am demo"); }
}
核心介面 AnnotatedElement (由 AccessibleObject 實現,Method/Class/Field 等繼承):
| 方法 | 說明 |
|---|---|
| 取得指定類型註解,無則 null | |
| getAnnotations() | 取得所有註解 (含繼承) |
| getDeclaredAnnotations() | 取得直接聲明的註解 |
| isAnnotationPresent(Class) | 檢查是否存在指定註解 |
public class AnnotationParser {
public static void main(String[] args) throws Exception {
String clazz = "com.yuanhh.annotation.AnnotationDemo";
Method[] methods = AnnotationParser.class.getClassLoader().loadClass(clazz).getMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(AuthorAnno.class)) {
AuthorAnno info = method.getAnnotation(AuthorAnno.class);
System.out.println("method: " + method);
System.out.println("name=" + info.name() + ", website=" + info.website() + ", revision=" + info.revision());
}
}
}
}
method: public void com.yuanhh.annotation.AnnotationDemo.demo() name= yuanhh , website= gityuan.com , revision= 2 method: public static void com.yuanhh.annotation.AnnotationDemo.main(String[]) name= yuanhh , website= gityuan.com , revision= 1
拿到註解資訊後可實現:自動代碼生成、運行時配置綁定、AOP 切點匹配、測試框架標記等進階功能。