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

Java 註解 (Annotation) 基礎概念完整解析:從元資料到標準註解

     編輯:Java 程式設計入門

什麼是註解?

Annotation(註解) 是 JDK 5.0 引入的一種元程式設計機制,讓開發者能將元資料(Metadata)關聯到程式元素(套件、類別、方法、欄位、參數、區域變數等)。註解本質上是一個介面(繼承 java.lang.annotation.Annotation),程式可透過反射讀取其屬性值,但註解本身不影響程式碼執行邏輯——JVM 執行時會忽略它們,需配合編譯期處理器(APT)、執行期框架(Spring、Hibernate 等)或工具(javadoc)才能發揮作用。

元資料三大分類

分類用途典型例子
文件生成從原始碼標記自動產出文件Javadoc 標籤 @param、@return
程式碼分析靜態分析、找潛在 Bug、架構檢查FindBugs、Error Prone、Checkstyle 自訂規則
編譯檢查編譯期強制語義約束@Override、@Deprecated、@SuppressWarnings

註解的兩個維度分類

依參數個數

  • 標記註解:無參數,單純以「存在與否」傳遞資訊。如 @Override。
  • 單值註解:僅一個參數,慣命名為 value()。如 @SuppressWarnings("unchecked")。
  • 完整註解:多個參數,各有名稱與預設值。

依用途來源

  • JDK 內建系統註解:@Override、@Deprecated、@SuppressWarnings、@SafeVarargs、@FunctionalInterface 等。
  • 元註解:用來註解「其他註解」的註解,定義於 java.lang.annotation。包含 @Target、@Retention、@Documented、@Inherited、@Repeatable、@Native。
  • 自訂註解:開發者自行定義,配合 APT 或執行期反射實現框架功能(如 Spring @Autowired、JPA @Entity)。

三大標準系統註解詳解

1. @Override — 編譯期斷言覆寫


class Fruit {
    public void displayName() { System.out.println("水果"); }
}
class Orange extends Fruit {
    @Override
    public void displayName() { System.out.println("橘子"); } // 正確
}
class Apple extends Fruit {
    @Override
    public void displayname() { System.out.println("蘋果"); } // 編譯錯誤:方法名拼寫錯誤,未真正覆寫
}

僅能修飾方法,防止拼寫錯誤、參數不符導致「以為覆寫實則多載」。

2. @Deprecated — 標記過時


class AppleService {
    @Deprecated
    public void showTaste() { System.out.println("脆甜"); }

    public void showTaste(int typeId) { /* 新版多型重載 */ }
}
  • 編譯器會對使用該元素的程式碼發出警告。
  • 具「傳染性」:繼承/覆寫過時方法的子類方法雖未標註,編譯器仍警告。
  • 搭配 Javadoc @deprecated 標籤說明替代方案。

3. @SuppressWarnings — 抑制特定編譯警告


@SuppressWarnings({ "rawtypes", "unchecked" })
public List<Fruit> getFruitList() {
    List<Fruit> list = new ArrayList(); // 原始類型警告
    return list;
}

@SuppressWarnings("unused")
public void test() {
    String unusedVar = "hello"; // 故意不使用,抑制未使用變數警告
}
常用參數值含義
deprecation使用過時 API
unchecked泛型未檢查轉換(如原始集合賦值給泛型變數)
fallthroughswitch 缺少 break 直落
serial可序列化類別缺少 serialVersionUID
all抑制以上所有

元註解速查表

元註解作用關鍵屬性
@Target限定註解可用程式元素ElementType[] value():TYPE、FIELD、METHOD、PARAMETER、CONSTRUCTOR、LOCAL_VARIABLE、PACKAGE、MODULE 等
@Retention定義註解保留階段RetentionPolicy value():SOURCE(源碼)、CLASS(預設、class 檔)、RUNTIME(執行期可反射)
@Documented標示應被 javadoc 納入 API 文件標記註解,無屬性
@Inherited允許子類別繼承父類別的此註解(僅限 TYPE)標記註解,配合 RUNTIME 反射時向上查找
@Repeatable允許同一元素重複套用該註解(JDK 8+)Class<? extends Annotation> value() 指定容器註解

自訂註解語法要點


@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
    String value() default ""; // 單一屬性慣命名 value()
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FruitColor {
    enum Color { RED, GREEN, BLUE }
    Color fruitColor() default Color.GREEN;
}
  • 以 @interface 定義,隱含繼承 Annotation 介面。
  • 屬性以無參數方法形式宣告,回傳型別限制:基本型別、String、Class、enum、Annotation、及其陣列。
  • 屬性只能用 public 或預設(package-private)修飾。
  • 可用 default 指定預設值。

註解處理機制

  1. 編譯期(APT):javax.annotation.processing.Processor,掃描源碼註解生成新原始碼/資源/類別(如 Lombok、MapStruct、Dagger)。
  2. 類別載入期:框架掃描 classpath 註解建構中繼模型(Spring 元件掃描、Hibernate 實體映射)。
  3. 執行期反射:AnnotatedElement.getAnnotation()、getAnnotations() 讀取 RUNTIME 註解屬性驅動邏輯(Spring AOP、JAX-RS 路由、JSON 序列化配置)。

總結

註解 = 標準化的元資料載體。
它不執行業務邏輯,但為工具鏈、框架、團隊協作提供結構化語義錨點。
善用 @Target/@Retention 明確語義邊界,配合 APT 或反射,將「約定」轉為「程式可驗證的契約」。

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