首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 程式設計入門

Java 註解(Annotation)核心技術全解析:從元註解到自定義註解解析實戰

     編輯:Java 程式設計入門

一、註解本質:比註釋更強大的元數據機制

Java 註解(Annotation)本質是「描述代碼的代碼」,屬於一種修飾符,與 public、static、transient 同級。不同於註釋僅在源碼階段給人看,註解能被編譯器、工具、運行時 JVM 讀取並觸發行為。

特性註釋 (// /* */)Javadoc (/** */)註解 (@Annotation)
作用階段僅源碼源碼→HTML文檔源碼、編譯期、運行時
可被程序讀取否僅文檔工具是(反射/APT)
可攜帶結構化數據否否是(屬性值)
可觸發代碼生成/邏輯否否是

二、四大元註解:定義註解的註解

@Target —— 限定註解能用在哪裡

@Target(ElementType.METHOD)
public @interface MyAnnotation {}

ElementType 枚舉值:

  • TYPE:類/接口/枚舉/註解類型
  • FIELD:屬性/枚舉常量
  • METHOD:方法
  • PARAMETER:參數
  • CONSTRUCTOR:構造器
  • LOCAL_VARIABLE:局部變量
  • ANNOTATION_TYPE:註解類型
  • PACKAGE:包

@Retention —— 定義註解生命週期

@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {}

三種策略:

  • SOURCE:編譯期丟棄(如 @Override、@SuppressWarnings)
  • CLASS:編入 .class,運行時不可見(默認值)
  • RUNTIME:運行時可通過反射讀取(自定義註解常用)

@Documented —— 包含在 Javadoc 中

被此元註解修飾的註解,生成 API 文檔時會保留。

@Inherited —— 註解自動繼承

若註解類型被 @Inherited 修飾,子類未顯式聲明該註解時,會自動向父類查找。

三、三大內建註解深度剖析

@Override

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.SOURCE)
public @interface Override {}
  • 僅用於方法
  • 編譯期檢查:父類是否存在同簽名方法
  • 防止拼寫錯誤導致「以為重寫實則重載」

@Deprecated

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(value={CONSTRUCTOR, FIELD, LOCAL_VARIABLE, METHOD, PACKAGE, PARAMETER, TYPE})
public @interface Deprecated {}
  • 標記「不建議使用」
  • 編譯器會發出警告
  • 運行時可見,工具可掃描

@SuppressWarnings

@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.SOURCE)
public @interface SuppressWarnings {
    String[] value();
}

常用抑制值:

  • deprecation:使用過時 API
  • unchecked:泛型未檢查轉換
  • serial:可序列化類缺少 serialVersionUID
  • all:抑制所有

四、自定義註解:定義屬於你的元數據

4.1 定義語法規則

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Inherited
public @interface MethodInfo {
    String author() default "unknown";
    String date();
    int version() default 1;
}

規則:

  • 用 @interface 關鍵字
  • 方法無參數、無拋出異常、無方法體
  • 返回類型限於:基本類型、String、Class、枚舉、註解、及其單維數組
  • 可用 default 指定默認值

4.2 使用示例

public class AnnotationTest {
    @MethodInfo(author="zhangsan", date="20240115")
    public static void main(String[] args) {
        System.out.println("Using custom annotation...");
    }
}

五、註解解析:讓註解「活」起來

註解本身是被動的元數據,必須由框架/工具主動解析才能產生作用。

5.1 編譯期解析(APT:Annotation Processing Tool)

  • 適用 @Retention(CLASS) 註解
  • 實現 AbstractProcessor,重寫 process()
  • 編譯器自動發現並調用
  • 典型應用:Lombok、MapStruct、Dagger、ButterKnife 代碼生成

5.2 運行時反射解析

  • 適用 @Retention(RUNTIME) 註解
  • 核心接口:java.lang.reflect.AnnotatedElement
public class AnnotationParser {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = AnnotationTest.class;
        for (Method method : clazz.getDeclaredMethods()) {
            MethodInfo info = method.getAnnotation(MethodInfo.class);
            if (info != null) {
                System.out.println("Method: " + method.getName());
                System.out.println("Author: " + info.author());
                System.out.println("Date:   " + info.date());
                System.out.println("Ver:    " + info.version());
            }
        }
    }
}

六、總結與避坑指南

  1. 生命週期選對:代碼生成用 SOURCE/CLASS,運行時決策用 RUNTIME
  2. Target 別漏寫:默認可用於所有位置,建議顯式限定
  3. 屬性類型受限:不能用集合、Map、自定義對象
  4. 繼承機制:類註解需 @Inherited 才能被子類繼承;方法註解不支持繼承
  5. 性能考量:運行時反射解析有開銷,熱路徑慎用或緩存結果

掌握註解機制,是理解 Spring、Hibernate、MyBatis 等主流框架核心原理的鑰匙,也是構建優雅 DSL、自動化代碼生成工具的基石。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved