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

在 Eclipse 3.1 體驗 J2SE 5.0 新特性(二):註解類型深度解析

     編輯:Java 相關知識

J2SE 5.0 里程碑

J2SE 5.0 (Tiger) 發布是 Java 語言發展史上重要里程碑,迄今為止 Java 程式設計領域最大進步。新特性包括:泛型、列舉類型、中繼資料/註解、自動拆箱/裝箱、可變參數、靜態導入、新執行緒框架。Eclipse 3.1 M4 起支援 J2SE 5.0 開發。

本系列介紹三大重要特性:列舉類型、註解類型、泛型,並示範在 Eclipse 3.1 開發環境中的應用。本文聚焦註解類型。

註解類型簡介

J2SE 5.0 支援中繼資料,在原始檔中稱為註解。開發者可在不改變原有邏輯下,在原始檔嵌入補充資訊。程式碼分析工具、開發工具、部署工具可透過這些資訊驗證或部署。例如希望某方法參數或回傳值不為 null,雖可在 JavaDoc 說明,但自然語言表達多樣,工具難以分析。使用註解即能輕鬆解決。

定義註解

使用 @interface 關鍵字聲明註解。最簡單範例:

public @interface TODO {}

可在註解中加入元素(類似方法,無需 getter/setter):

public @interface TODO {
    String priority();
}

使用自訂註解:

@TODO(priority="high")
public void calculate() { /* body */ }

單一元素可簡寫:@TODO("high")。可定義多元素與預設值:

public @interface TODO {
    String priority();
    String owner();
    boolean testable() default true;
}

使用時可省略預設值元素:

@TODO(priority="high", owner="Catherine")
public void calculate() { /* testable 使用預設 true */ }

Eclipse 3.1 建立註解精靈

  1. 建立 Plug-in 專案 com.catherine.lab.annotation.demo。
  2. Package Explorer 選中套件,New > Other > Java > Annotation。
  3. 輸入註解名稱 TODO,點擊 Finish 生成程式碼。

建立註解精靈 註解精靈生成的程式碼

註解類型分類

依傳入參數數目分三種:

  1. 標記註解:最簡單,無元素定義。@Override、@Deprecated 屬此類。語法:@MarkerAnnotation。若註解所有元素皆有預設值,也可視為標記註解。
  2. 單值註解:單一元素。語法:@SingleValueAnnotation("some value")。
  3. 全值註解:完整語法。@MultipleValueAnnotation(key1=value1, key2=value2, key3=value3)。

J2SE 內建註解

J2SE 5.0 預定義三種註解:

  • @Override (java.lang.Override):表示當前方法覆寫父類方法,若父類無對應方法則編譯錯誤。
  • @Deprecated (java.lang.Deprecated):不建議使用當前方法或欄位。
  • @SuppressWarnings (java.lang.SuppressWarnings):關閉編譯器警告,編譯 1.5 前程式碼時避免大量無關警告。

@Override 實戰範例

在模板方法模式中極具價值。抽象類定義主要控制流,子類透過覆寫父類方法實現邏輯。若父類提供預設實作,子類可選擇不實作。問題在於:若子類想覆寫但拼錯方法名,編譯器會視為新方法而非覆寫,難以發現。使用 @Override 後,拼錯會導致編譯錯誤提示父類無對應方法。

模板方法的類圖

public abstract class BaseClass {
    public void doWork() {
        doPartI();
        doPartII();
    }
    public abstract void doPartI();
    public void doPartII() {}
}

public class SubClass extends BaseClass {
    public void doPartI() {}
    @Override
    public void doPortII() {  // 故意拼錯
        System.out.println("override the method of superclass");
    }
}

Override 應用範例

中繼註解

J2SE 5.0 提供四種用於註解的註解類型:

  1. @Target:指定註解適用的程式元素類型。如 @Override 僅能修飾方法。範例:@Target({ElementType.METHOD}) 限定 @TODO 僅能修飾方法,修飾類別或欄位會編譯錯誤(見圖 5)。
  2. @Retention:保留策略三選一:
    • RetentionPolicy.SOURCE:編譯後從 class 檔移除
    • RetentionPolicy.CLASS:保留在 class 檔,VM 不處理(預設)
    • RetentionPolicy.RUNTIME:保留在 class 檔,VM 處理(運行時需透過反射讀取註解必須指定此策略)
  3. @Documented:將註解作為公共 API 一部分。
  4. @Inherited:若註解定義使用此中繼註解,修飾某類別時,其子類別也被該註解修飾。

註解應用實戰

動態查找註解

定義註解後可開發分析工具解讀,通常利用 Java 反射特性。範例定義 @TODO(修飾方法)與 @TOFORMATE(修飾欄位),在 MyCalculator 使用,TestCalculator 透過反射查找使用這些註解的方法與欄位(見清單 12-15)。運行結果與定義一致,可在運行時獲取註解使用資訊。

運行結果

以註解取代 Visitor 模式

J2SE 5.0 前常用 Visitor 模式 為既有類別結構添加方法而不修改原類別。例如輸出物件部分資料至特定格式檔案。Visitor 實作需在 Employee 加入 export 方法接受 Exporter 物件並呼叫 visit()。定義 Exporter 抽象類,繼承並覆寫 visit() 實現不同格式輸出。缺點:若 Employee 新增欄位,對應 Visitor 類也需修改,違反「開放擴充、封閉修改」原則。

使用 Visitor 模式實現格式輸出

使用註解替代:定義 @Exportable 註解,建立抽象解析器 ExportableGenerator 傳入 Employee 物件,解析器查找使用 @Exportable 的欄位並按格式輸出。定義見清單 16。Employee、Regular、Vendor、Contractor、Supplemental 類別使用 @Exportable 標記需輸出欄位(清單 17-21)。TestExportable 使用 ExportableGenerator 產生輸出檔(清單 22)。ExportableGenerator 定義基本框架(清單 23),TXTExportableGenerator 繼承並實作具體輸出格式(清單 24)。使用者可繼承實作抽象方法定義期望格式。

範例將 Employee 物件部分內容輸出至 C:\test.output,結果見圖 12。透過此法可動態生成物件欄位輸出,無需在程式碼寫死輸出欄位。若需豐富格式,可定義多種註解類型,透過解析不同註解與屬性實現格式化輸出。

輸出結果

小結

中繼資料即「關於資訊的資訊」。程式碼分析、測試、部署工具常用中繼資料產生配置資訊與控制邏輯,通常利用 Java 反射重構並解釋中繼資料。新技術改變程式設計與開發者設計思維。註解不僅用於程式碼分析、測試/部署框架,應用範圍極廣。善用中繼資料可提升軟體品質與可維護性。

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