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

Java 註解(Annotation)入門:從內建到自定義、保留策略與反射解析完整指南

     編輯:Java 相關知識

Annotation(註解)自 Java 5 引入以來,已成為框架開發、配置元數據、編譯檢查的基石。本文從四大內建註解切入,帶你手寫自定義註解、理解 @Target、@Retention、@Documented 元註解語義,並示範如何透過反射在運行時解析註解屬性,打通「聲明式編程」最後一公里。

一、四大內建註解速覽

註解用途適用位置
@Override標示方法覆寫父類/介面方法,編譯器檢查簽名一致性方法
@Deprecated標示 API 過時,編譯器發出警告,建議遷移類、方法、欄位、建構子、套件、參數等所有元素
@SuppressWarnings壓制編譯器特定警告(如 unchecked、rawtypes、deprecation)類、方法、欄位、區域變數等
@EntityJPA 標示可持久化實體類(非 JDK 內建,屬 javax.persistence)類

二、自定義註解:手把手實作

1. 單屬性註解(慣用 value 名稱)

package com.example.annotation;

import java.lang.annotation.*;

@Target(ElementType.TYPE)           // 只能標註在類/介面/Enum/註解上
@Retention(RetentionPolicy.RUNTIME) // 保留至運行期,可被反射讀取
@Documented                         // 納入 Javadoc 生成的 API 文檔
public @interface Description {
    String value(); // 單一屬性,名稱慣用 value,使用時可省略屬性名
}

2. 多屬性註解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface AuditLog {
    String description();   // 業務描述
    boolean enabled() default true; // 可提供預設值
    int level() default 1;  // 審計等級
}

3. 使用範例

@Description("訂單核心領域模型")
public class Order {

    @AuditLog(description = "建立訂單", level = 2)
    public void create() { /* ... */ }

    @AuditLog(description = "取消訂單", enabled = false)
    public void cancel() { /* ... */ }
}

三、元註解深度解析

元註解關鍵屬性語義
@Target ElementType[] value 限制註解可標註的程式元素類型:
  • TYPE:類、介面、Enum、註解
  • FIELD:欄位(含 enum 常數)
  • METHOD:方法
  • PARAMETER:方法參數
  • CONSTRUCTOR:建構子
  • LOCAL_VARIABLE:區域變數
  • ANNOTATION_TYPE:註解類型本身
  • PACKAGE:套件(package-info.java)
  • TYPE_PARAMETER、TYPE_USE (Java 8+):泛型型別參數、型別使用位置
@Retention RetentionPolicy value 生命週期策略:
  • SOURCE:僅原始碼階段存在,編譯時丟棄(如 @Override、@SuppressWarnings)
  • CLASS:編譯進 .class,**預設值**,但 JVM 載入時不載入(需自定義 ClassLoader 或 APT 處理)
  • RUNTIME:保留至運行期,可被反射 API 讀取(框架常用)
@Documented 無 指示 Javadoc 工具將此註解類型包含在生成的 API 文檔中。缺省不顯示。
@Inherited 無 **僅對 @Target(TYPE) 有效**。標註此元註解的註解,若父類被標註,子類透過 getAnnotation 可繼承獲取(不包含介面實作)。
@Repeatable Class<? extends Annotation> value (Java 8+) 允許同一位置重複標註同類型註解,需配合容器註解。

四、屬性類型限制

註解屬性(方法)僅支援以下類型:

  • 八大基本型別:byte, short, int, long, float, double, char, boolean
  • String
  • Class (含型別參數)
  • Enum
  • Annotation (嵌套註解)
  • 以上類型的一維陣列 (如 String[])

⚠️ 不支援:null 作為預設值、泛型、多維陣列、物件實例。

五、反射解析註解:運行時讀取元數據

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AnnotationParser {
    public static void main(String[] args) throws Exception {
        Class<?> clazz = Class.forName("com.example.annotation.Order");

        // 1. 解析類級註解
        if (clazz.isAnnotationPresent(Description.class)) {
            Description desc = clazz.getAnnotation(Description.class);
            System.out.println("📦 類描述: " + desc.value());
        }

        // 2. 解析方法級註解
        for (Method method : clazz.getDeclaredMethods()) {
            if (method.isAnnotationPresent(AuditLog.class)) {
                AuditLog audit = method.getAnnotation(AuditLog.class);
                System.out.printf("🔧 方法: %-10s | 描述: %-10s | 啟用: %b | 等級: %d%n",
                        method.getName(), audit.description(), audit.enabled(), audit.level());
            }
        }
    }
}

輸出結果

📦 類描述: 訂單核心領域模型
🔧 方法: create      | 描述: 建立訂單    | 啟用: true  | 等級: 2
🔧 方法: cancel     | 描述: 取消訂單    | 啟用: false | 等級: 1

六、進階應用模式

  1. 編譯期處理 (APT):配合 @Retention(SOURCE) + javax.annotation.processing,編譯階段生成代碼/配置/檢查(如 Lombok、MapStruct、Dagger)。
  2. 運行時掃描:Spring、Hibernate、JUnit 等框架啟動時掃描類路徑下的註解,構建 Bean 定義、實體映射、測試計劃。
  3. 參數註解:@Target(PARAMETER) 結合 Method.getParameterAnnotations() 實現聲明式參數校驗、綁定(如 Spring MVC @RequestParam)。

七、最佳實踐清單

  • ✅ 明確標註 @Target 與 @Retention,避免濫用預設值導致語義模糊。
  • ✅ 單屬性註解**務必命名為 value**,使用時可簡寫 @Anno("val")。
  • ✅ 屬性提供合理 default 值,降低使用者負擔。
  • ✅ 文檔化註解加上 @Documented,方便 API 使用者查閱。
  • ⚠️ 運行期反射解析有性能開銷,熱路徑建議緩存 Annotation 物件或改用編譯期處理。

結語

Annotation 是 Java「聲明式編程」的基石。掌握 元註解語義、屬性類型限制、保留策略選擇、反射解析 API,即可從「使用框架註解」進階到「設計領域專用註解」,構建乾淨、可擴展、自文檔化的代碼庫。

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