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

Java 註解完整教學:從基礎語法到類型註解與可插拔型別系統

     編輯:Java 綜合教學

Java 註解概述

註解 是一種元資料格式,提供關於程式的資料,但不屬於程式碼本身,且不直接影響被註解代碼的運作。主要用途:

  • 提供編譯器資訊——檢查錯誤或抑制警告
  • 編譯期與部署期處理——工具可處理註解產生程式碼、XML 等產出物
  • 執行期處理——部分註解在執行期被檢視(如透過反射)

本教學涵蓋註解使用位置、應用方式、預定義註解類型、自訂註解、元註解、類型註解、可插拔型別系統與重複註解。

註解基礎

註解語法

最簡形式:

@Entity

@ 標示後續為註解。帶元素的註解:

@Author(name = "Benjamin Franklin", date = "3/27/2003")
class MyClass { ... }

或單一元素可省略元素名:

@SuppressWarnings(value = "unchecked")
void myMethod() { ... }

無元素時括號可省略(如 @Override)。可在同一宣告套用多個註解:

@Author(name = "Jane Doe") @EBook
class MyClass { ... }

同類型重複註解自 Java SE 8 支援(詳見重複註解章節)。註解類型可為 JDK 內建(java.lang、java.lang.annotation)或自訂(如上例 @Author、@EBook)。

註解適用目標

傳統上用於宣告:類別、欄位、方法等程式元素,慣例每行一個註解。Java SE 8 起擴展至型別使用場合:

  • 類別實例化:new @Interned MyObject();
  • 型別轉換:myString = (@NonNull String) str;
  • 實作介面:class UnmodifiableList<T> implements @Readonly List<@Readonly T> { ... }
  • 拋出異常宣告:void monitorTemperature() throws @Critical TemperatureException { ... }

此類註解稱為類型註解,配合可插拔型別系統強化靜態檢查。

宣告註解:以類別檔頭資訊為例

傳統以註解區塊記錄作者、版本等資訊:

public class Generation3List extends Generation2List {
    // Author: John Doe
    // Date: 3/17/2002
    // ...
}

改用註解須先定義註解類型:

@interface ClassPreamble {
    String author();
    String date();
    int currentRevision() default 1;
    String lastModified() default "N/A";
    String lastModifiedBy() default "N/A";
    String[] reviewers();
}

@interface 關鍵字定義註解類型(本質為介面)。元素宣告類似方法,可指定預設值。使用時填寫值:

@ClassPreamble(
    author = "John Doe",
    date = "3/17/2002",
    currentRevision = 6,
    lastModified = "4/12/2004",
    lastModifiedBy = "Jane Doe",
    reviewers = {"Alice", "Bob", "Cindy"}
)
public class Generation3List extends Generation2List { ... }

預定義註解類型

Java 語言內建註解

java.lang 定義:@Deprecated、@Override、@SuppressWarnings、@SafeVarargs、@FunctionalInterface。

  • @Deprecated:標記棄用元素,編譯器發出警告。配合 Javadoc @deprecated 標籤說明替代方案(注意大小寫差異)。
  • @Override:標示重寫父類別方法,編譯器驗證簽章一致性,防止拼字錯誤導致意外多載。
  • @SuppressWarnings:抑制指定警告(如 "deprecation"、"unchecked"),多重警告用陣列語法:@SuppressWarnings({"unchecked", "deprecation"})。
  • @SafeVarargs:斷言可變參數方法/建構子不執行潛在不安全操作,抑制相關未檢查警告。
  • @FunctionalInterface(Java 8):標示函數式介面(單一抽象方法),編譯器強制檢查。

元註解:註解其他註解

定義於 java.lang.annotation:

  • @Retention:指定保留策略——SOURCE(原始碼層級,編譯器捨棄)、CLASS(類別檔保留,JVM 忽略,預設)、RUNTIME(JVM 保留,執行期可透過反射讀取)。
  • @Documented:指示 Javadoc 包含此註解(預設不包含)。
  • @Target:限制註解適用程式元素——ANNOTATION_TYPE、CONSTRUCTOR、FIELD、LOCAL_VARIABLE、METHOD、PACKAGE、PARAMETER、TYPE、TYPE_PARAMETER、TYPE_USE(後兩者 Java 8 新增)。
  • @Inherited:允許子類別繼承父類別此註解(僅限類別宣告,預設 false)。
  • @Repeatable(Java 8):標示註解可重複套用於同一宣告,需配合容器註解(詳後節)。

類型註解與可插拔型別系統

Java 8 前註解僅限宣告,Java 8 擴展至任意型別使用場合(實例化、轉型、介面實作、拋出異常等)。此設計為改進 Java 強型別檢查鋪路:Java 8 未內建型別檢查框架,但允許編寫/下載可插拔模組整合編譯器。

範例:確保變數永不為 null,自訂 @NonNull 註解:

@NonNull String str;

編譯時掛載 NonNull 模組,編譯器偵測潛在空指標風險並警告。修正所有警告後,執行期該類錯誤不再發生。可疊加多檢查模組(正則、互斥鎖等),知名第三方框架如 Checker Framework(華盛頓大學)提供豐富模組。

重複註解

Java 8 允許同一註解類型重複套用於同一宣告。範例:排程服務需在每月最後一天與每週五 23:00 執行:

@Schedule(dayOfMonth="last")
@Schedule(dayOfWeek="Fri", hour="23")
public void doPeriodicCleanup() { ... }

或類別層級多角色通知:

@Alert(role="Manager")
@Alert(role="Administrator")
public class UnauthorizedAccessException extends SecurityException { ... }

實作重複註解兩步驟

  1. 宣告可重複註解類型,標註 @Repeatable 指定容器註解類型:
import java.lang.annotation.Repeatable;
@Repeatable(Schedules.class)
public @interface Schedule {
    String dayOfMonth() default "first";
    String dayOfWeek() default "Mon";
    int hour() default 12;
}
  1. 宣告容器註解類型,包含陣列元素 value,元件型別為可重複註解:
public @interface Schedules {
    Schedule[] value();
}

編譯器自動將重複註解封裝於容器註解中。未標註 @Repeatable 的註解重複使用會編譯錯誤。

擷取重複註解

反射 API 新增方法掃描容器註解一次回傳多個註解(如 AnnotatedElement.getAnnotations(Class)),舊方法 getAnnotationByType(Class) 僅回傳單一註解,相容既有程式碼。

設計考量

設計註解類型時需考量基數(零次、一次、多次)、適用目標(@Target),確保 API 彈性與類型安全並重。

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