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

Java Annotation 深度解析(二):Meta-Annotation 完整解讀、標準註解實戰與自訂註解處理器入門

     編輯:Java 程式設計入門

Meta-Annotation(元註解)完整定義

定義於 java.lang.annotation 套件,用於約束註解本身的行為:

Meta-Annotation用途關鍵屬性
@Target限定註解可標註的程式元素類型value() — ElementType[]
@Retention限定註解保留階段value() — RetentionPolicy
@Documented標示該註解應出現在 Javadoc 中無屬性
@Inherited標示該註解可被子類別繼承(僅對類別有效)無屬性

@Target — ElementType 列舉值

TYPE          // 類別、介面、Enum、註解類型
FIELD         // 欄位(含 Enum 常數)
METHOD        // 方法(不含建構子)
PARAMETER     // 方法參數
CONSTRUCTOR   // 建構子
LOCAL_VARIABLE // 區域變數、catch 參數
ANNOTATION_TYPE // 註解類型(元註解)
PACKAGE       // 套件宣告
MODULE        // Java 9+ 模組宣告
TYPE_PARAMETER  // Java 8+ 型別參數
TYPE_USE        // Java 8+ 型別使用處

@Retention — RetentionPolicy 三階段

SOURCE  // 僅原始碼階段,編譯器捨棄,不進 .class(如 @Override、@SuppressWarnings)
CLASS   // 進 .class,但 VM 載入時捨棄(預設值)
RUNTIME // 進 .class 且 VM 載入時保留,可透過反射讀取(自訂註解常用)

三大標準註解

註解套件用途典型場景
@Deprecatedjava.lang標記 API 已過時,編譯器發出警告舊版方法、欄位、類別
@Overridejava.lang宣告方法覆寫父類別/介面方法,編譯器驗證簽名所有覆寫方法強烈建議加上
@SuppressWarningsjava.lang壓制編譯器特定警告@SuppressWarnings("unchecked")、"rawtypes"、"deprecation"

標準註解實戰範例

package sz.starbex.bill.annotation;

import java.util.ArrayList;
import java.util.List;

public class StandardAnnotationsDemo {
    public static void main(String[] args) {
        StandardAnnotationsDemo demo = new StandardAnnotationsDemo();
        System.out.println(demo); // 呼叫 toString()
        demo.doSomething();       // 過時方法
        demo.testSuppressWarnings();
    }

    @Override
    public String toString() {
        return "自訂 toString 輸出";
    }

    @Deprecated
    public void doSomething() {
        System.out.println("此方法已過時,請改用 newMethod()");
    }

    @SuppressWarnings("unchecked") // 壓制「未檢查轉型」警告
    public void testSuppressWarnings() {
        List list = new ArrayList(); // 原始型別 List
        list.add("KKKK");            // 型別不安全
        // 編譯器不再警告 unchecked
    }
}

自訂註解設計範本

import java.lang.annotation.*;

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnnotation {
    String value() default "";
    int priority() default 0;
    String[] tags() default {};
}

運行時讀取註解(反射)

public class AnnotationReader {
    public static void main(String[] args) throws Exception {
        Class clazz = StandardAnnotationsDemo.class;
        
        // 類別層級
        if (clazz.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation ann = clazz.getAnnotation(MyAnnotation.class);
            System.out.println("類別註解: " + ann.value() + ", priority=" + ann.priority());
        }
        
        // 方法層級
        for (var method : clazz.getDeclaredMethods()) {
            if (method.isAnnotationPresent(MyAnnotation.class)) {
                MyAnnotation ann = method.getAnnotation(MyAnnotation.class);
                System.out.println("方法 " + method.getName() + ": " + ann.value());
            }
        }
    }
}

進階:註解處理器(Annotation Processor)

  • 編譯期掃描註解、產生程式碼/資源/錯誤訊息。
  • 實作 javax.annotation.processing.Processor,註冊於 META-INF/services/javax.annotation.processing.Processor。
  • 經典應用:Lombok、MapStruct、Dagger、Room、ButterKnife(舊)。
  • 啟動方式:javac -processor com.example.MyProcessor ... 或 IDE 自動偵測。

最佳實務

  1. @Target 盡可能精確限定,避免濫用。
  2. @Retention(RUNTIME) 僅在需反射讀取時使用;純編譯期驗證用 SOURCE,減少 .class 體積。
  3. 屬性命名慣例:單一屬性用 value(),多屬性用語意化名稱。
  4. 提供 default 值提升易用性。
  5. 文件化註解語意、預期用法、處理器行為。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved