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

Java 註解 @interface 完整指南:從基礎到反射實戰

     編輯:Java 相關知識

在 Java 開發中,註解已經成為不可或缺的工具。它不僅能標記程式碼,更能通過反射機制在編譯期、類載入期或執行期發揮作用。本文將系統梳理 Java 註解的核心概念、內建註解、元註解以及自定義註解的實戰應用。

什麼是註解?

註解(Annotation)本質上是一個繼承了 java.lang.annotation.Annotation 介面的特殊介面,使用 @interface 關鍵字定義。它就像貼在程式碼上的標籤,編譯器、開發工具或執行期框架可以通過反射讀取這些標籤,進而執行相應邏輯。

三大內建標準註解

@Override

用於方法宣告,表示該方法覆寫父類方法。若方法簽名錯誤(如大小寫不匹配 ToString() vs toString()),編譯器會直接報錯,避免低級錯誤進入生產環境。

@Deprecated

標記類、方法或欄位已過時,不建議繼續使用。編譯器會在使用處發出警告,提醒開發者遷移到新 API。

@SuppressWarnings

壓制編譯器警告,常見參數有 unchecked(泛型未檢查)、deprecation(使用過時 API)等。

元註解:註解的註解

元註解用於修飾其他註解的定義,決定註解的生命週期、作用目標等核心屬性。

@Retention:生命週期策略

定義註解資訊保留到哪個階段,對應 RetentionPolicy 三種枚舉值:

  • SOURCE:僅原始碼保留,編譯器直接丟棄,不進入 .class 檔案(如 @Override、@SuppressWarnings)。
  • CLASS(預設):保留在 .class 位元組碼中,但 JVM 執行期不載入,無法通過反射讀取。
  • RUNTIME:保留至執行期,JVM 載入類時會將註解載入記憶體,可通過反射 API 讀取(如 @Deprecated、自定義框架註解)。

@Target:作用目標限制

限制註解可應用的程式元素類型,對應 ElementType 枚舉:

  • TYPE:類、介面、枚舉
  • METHOD:方法
  • FIELD:欄位(包含枚舉常數)
  • PARAMETER:方法參數
  • CONSTRUCTOR:建構子
  • LOCAL_VARIABLE:區域變數
  • ANNOTATION_TYPE:另一個註解
  • PACKAGE:套件宣告

例如 @Target(ElementType.METHOD) 限定該註解只能用在方法上,若強行用在類上會編譯報錯。

自定義註解與屬性定義

自定義註解語法類似介面,方法即為屬性,支援預設值:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {
    String value() default "defaultVal";  // 單一屬性名為 value 時使用可省略屬性名
    String hello() default "gege";
    String world();
    int[] array() default {2, 4, 5, 6};
    TrafficLamp lamp();                    // 枚舉類型屬性
    TestAnnotation lannotation() default @TestAnnotation(value="ddd"); // 註解嵌套
    Class<?> style() default String.class; // Class 類型屬性
}

註解屬性的類型限制

屬性類型僅限:基本型別、String、Class、枚舉、註解、以及上述類型的一維陣列。

反射讀取註解實戰

只有標記 @Retention(RetentionPolicy.RUNTIME) 的註解才能在執行期通過反射獲取:

// 類級別註解讀取
if (MyTest.class.isAnnotationPresent(MyAnnotation.class)) {
    MyAnnotation ann = MyTest.class.getAnnotation(MyAnnotation.class);
    System.out.println(ann.hello()); // 輸出屬性值
}

// 方法級別註解讀取
Method method = MyTest.class.getMethod("output");
if (method.isAnnotationPresent(MyAnnotation.class)) {
    MyAnnotation ann = method.getAnnotation(MyAnnotation.class);
    // 獲取陣列、嵌套註解、Class 等複雜屬性
    System.out.println(ann.array().length);
    System.out.println(ann.lannotation().value());
    System.out.println(ann.style());
}

// 獲取方法上所有 RUNTIME 註解
Annotation[] annotations = method.getAnnotations();
for (Annotation a : annotations) {
    System.out.println(a.annotationType().getName());
}

關鍵細節總結

  1. value 屬性慣例:若註解只有一個屬性且命名為 value,使用時可直接寫 @MyAnnotation("xxx") 省略屬性名。
  2. 預設值限制:屬性不能有 null 預設值,需用空字串或特定常量代替。
  3. 繼承關係:註解不支援繼承,所有註解隱式繼承 java.lang.annotation.Annotation 介面。
  4. 文檔化:加上 @Documented 元註解可讓 Javadoc 包含該註解資訊。

掌握註解機制,不僅能看懂 Spring、Hibernate 等主流框架的核心運作原理,更能編寫優雅的聲明式程式碼,實現關注點分離與框架級擴展。

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