<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    afunms

    My Software,My Dream—Forge a more perfect NMS product.

    充分利用Java元數(shù)據(jù)

    http://www.oracle.com/technology/global/cn/pub/articles/hunter_meta.html

    了解如何使用 J2SE 5.0 中提供的元數(shù)據(jù)批注

    最新的 J2SE 5.0 版本(也以代號 "Tiger" 著稱)為 Java 語言引進(jìn)了許多變化,這些變化旨在使 Java 編程更有表現(xiàn)力、更加開發(fā)人員友好和更安全。我在 2003 年 9 月的一篇題目為“Java 即將發(fā)生巨大變化”的文章中介紹了許多 Java 新特性。我沒有介紹的一個重大的變化 — 那時還沒有完整概述它 — 是 Java 的元數(shù)據(jù)工具。從本文開始,在一個新的分為四個部分的文章系列中,我將從一年前離開的地方繼續(xù)向您顯示如何充分利用 Java 的元數(shù)據(jù)。

    在第一篇文章中,我將說明元數(shù)據(jù)的用途并演示如何使用在核心的 J2SE 資料庫中提供的元數(shù)據(jù)批注。

    在第二篇文章中,我將顯示如何編寫您自己的批注(首先編寫類似 @Copyright 的簡單的批注,然后看看與核心語言中內(nèi)置的那些批注類似的更高級的批注)。

    在第三篇文章中,我將演示工具如何在構(gòu)建時使用批注(創(chuàng)建新的源文件或支持文件)以及程序如何在運行時使用批注(以改變代碼的行為)。

    在最后的第四篇文章中,我將介紹如何利用在 JSR-181 下開發(fā)的標(biāo)準(zhǔn)元數(shù)據(jù)批注的幫助使編輯和部署 Web 服務(wù)在未來變得更容易(Oracle 是 JSR-181 的專家組的成員,并且是在開發(fā)工具中增加對設(shè)計時元數(shù)據(jù)的支持的一個積極的擁護(hù)者。)

    元數(shù)據(jù)

    我承認(rèn)當(dāng)我第一次看到 JSR-175 的提案“用于 Java 編程語言的元數(shù)據(jù)工具”(在 2004 年 9 月發(fā)布;Oracle 也是該專家組的成員)時,我預(yù)測它將創(chuàng)建必須放在 JAR 的 META-INF 目錄下的另一個屬性文件,或者必須與 JAR 捆綁的另一個 XML 部署描述符。幸運的是,這不是元數(shù)據(jù)要做的。事實上,它正好相反。Java 的新的元數(shù)據(jù)工具提供了從 Java 代碼內(nèi)部批注 Java 代碼的一種標(biāo)準(zhǔn)方式。它使您能夠在要說明的元素的旁邊放置描述性的元數(shù)據(jù)。

    當(dāng)討論元數(shù)據(jù)時,您將經(jīng)常看到幾個類似的術(shù)語,因此下面提供了一個小術(shù)語表來幫助您了解它們的差異:

    術(shù)語 定義
    元數(shù)據(jù) 關(guān)于數(shù)據(jù)的數(shù)據(jù)。JSR-175 的目標(biāo)是在 Java 語言中提供元數(shù)據(jù)工具。
    批注 一種特殊的 Java 結(jié)構(gòu),用來修飾類、方法、字段、參數(shù)、變量、構(gòu)造器或包。它是 JSR-175 選擇用來提供元數(shù)據(jù)的工具。
    批注類型 具有特殊實施的各種命名批注
    屬性 由批注指定的一個特殊的元數(shù)據(jù)項目。有時可以和批注交替使用

     

    例如:富士蘋果有一個屬性:它是紅色的。假定有一個 FujiApple 類,您可以使用 @Color 批注類型的一個批注來指定它的顏色。通過這么做,您就提供了關(guān)于蘋果的元數(shù)據(jù)。

    自 1.0 版以來在 Java 中一直存在對元數(shù)據(jù)的需求。Java 從來沒有提供記錄元數(shù)據(jù)的標(biāo)準(zhǔn)機(jī)制,因而我們編程人員找到了各種技巧和竅門使用任意的工具來添加元數(shù)據(jù)。您看到在 J2SE 1.4 和更低版本中使用元數(shù)據(jù)的一些地方有:

    • transient 關(guān)鍵字
    • Serializable 標(biāo)記接口
    • SingleThreadModel servlet 接口
    • web.xml 部署描述符內(nèi)部的元素
    • META-INF/MANIFEST.MF 文件
    • BeanInfo 接口
    • @deprecated Javadoc 注釋
    • 所有的 XDoclet Javadoc 標(biāo)記。

     

    當(dāng)使用這些技巧時,您可能沒有想到您正在添加元數(shù)據(jù),但事實上您的確在添加元數(shù)據(jù)。上述方法存在的問題是它們都是解決同一問題的不同方法,但通用性不好。每一種方法都至少有一個缺點在新的元數(shù)據(jù)工具中得到了解決。

    對于這個列表中的一些方法,局限很明顯。使用關(guān)鍵字不能伸縮;您不能使用用戶自己定義的關(guān)鍵字。標(biāo)記接口沒有提供除它們的存在性之外的任何信息(即,它們沒有帶參數(shù)),并且它們只能處理類,而不能處理字段或方法或包。

    列表中的其他一些方法可能看起來合理。使用 XML 支持文件似乎是個好主意,而事實上在許多情況下仍是個好主意。但對于我們使用 XML 文件的許多用途,例如指示類的哪一個方法應(yīng)當(dāng)看作是 web 服務(wù),在 Java 代碼內(nèi)部將規(guī)則直接放在方法的旁邊將更加高效。利用元數(shù)據(jù),您可以使 XML 描述符文件僅包含與部署相關(guān)的決策。

    該列表中可能最高效的元數(shù)據(jù)的用法是 @deprecated Javadoc 注釋和在其鏡像中創(chuàng)建的 XDoclet 標(biāo)記。這可能是 JSR-175 語法為什么看起來與 @deprecated 標(biāo)記非常類似的原因(正如我們將在下一部分中看到的那樣)。

    批注

    批注可以很容易地附加到代碼結(jié)構(gòu)上。您可以寫一個 "at" 符號 (@),然后是批注類型名稱,并將批注直接放在要批注的項目前面。下面是一個簡單的例子:

    import javax.jws.WebService;
    import javax.jws.WebMethod;
    @WebService
    public class HelloWorldService {
    @WebMethod
    public String helloWorld() {
    return "Hello World!";
    }
    }
    

     

    當(dāng)部署在正確的環(huán)境中時,增加 @WebService@WebMethod 批注將指示 web 服務(wù)環(huán)境將該類變?yōu)?web 服務(wù)。

    您可以批注方法、類、字段、參數(shù)、變量、構(gòu)造器甚至整個包(利用一個特殊的外部 package-info.java 文件)。批注可以在括號內(nèi)帶任意數(shù)量的命名參數(shù)。下面是使用批注進(jìn)行修飾以創(chuàng)建 web 服務(wù)的一個更高級的示例類。它包含了一個理論上的 JNDI 環(huán)境變量查找:

    @WebService(
    name = "PingService",
    targetNamespace="http://acme.com/ping"
    )
    @SOAPBinding(
    style=SOAPBinding.Style.RPC,
    use=SOAPBinding.Use.LITERAL
    )
    public class Ping {
    public @env double level = 500.0;  // JNDI lookup
    public @WebMethod(operationName = "Foo") {
    void foo() { }
    }
    }
    

     

    這個例子顯示了附加到類、變量和方法(在類上實際上有兩個方法)上的批注。@env 批注沒有任何參數(shù),因此它不需要括號。其他批注有一個或更多的命名參數(shù)。

    當(dāng)創(chuàng)建新的批注類型時,您將限定允許哪些參數(shù)名以及它們的類型。批注接受的類型是嚴(yán)格限定的;它們只可以是基本類型、String、Class、枚舉類型、批注類型和前面這些類型的數(shù)組。傳遞的參數(shù)必須始終是非空的編譯時常量。

    要了解本示例中顯示的批注有什么效果必須等到本系列的第四篇文章。讓我們開始看看 J2SE 5.0 提供的簡單的批注類型:@Override、@Deprecated@SuppressWarnings。

    內(nèi)置的批注

    當(dāng)我們看這三種標(biāo)準(zhǔn)的用戶級批注時,必須考慮:在可以提供的所有可能的批注類型中,為什么 Tiger 恰恰提供三種?原因是提供大量的標(biāo)準(zhǔn)批注并不是目標(biāo)所在。

    JSR-175 的宗旨嚴(yán)格規(guī)定了它是要定義一個元數(shù)據(jù)工具。編寫自定義批注類型的任務(wù)留給了編程人員,而編寫一組標(biāo)準(zhǔn)的批注類型的任務(wù)留給了其他 JSR。例如,有一個新的名稱為“Java 平臺的通用批注”的 JSR-250,其宗旨是“為 J2SE 和 J2EE 平臺中的通用的語義概念開發(fā)適用于各種技術(shù)的批注”。JSR-250 計劃在 2005 年春天的某個時候在 javax.annotations 程序包中提供它的標(biāo)準(zhǔn)的批注集。還有之前提到的 JSR-181,它將使得在 J2EE 容器中編寫 Web 服務(wù)變得更容易(我們將在本系列中的第四篇文章中進(jìn)行介紹)。事實上,大多數(shù)新的企業(yè) JSR(從 Servlets 2.5 到 EJB 3.0 到 JDBC 4.0)都在考慮批注可以提供哪些優(yōu)點。

    @Override

    第一個 J2SE 標(biāo)準(zhǔn)批注 @Override 使您能夠在代碼中增加新的可選的編譯器檢查。它在方法中存在表示該方法用于覆蓋父類中的方法。如果編譯器檢測到該方法實際上沒有覆蓋任何東西,那么將出現(xiàn)編譯錯誤。經(jīng)常使用,@Override 可以幫助您避免當(dāng)方法標(biāo)記沒有完全匹配時 — 當(dāng)多態(tài)變?yōu)椋梢苑Q之為)“單態(tài)” ("unimorphism") 時 — 將得到的細(xì)微的 bug。

    例如,以下代碼可能看起來很合理:

    public class OverrideExample {
    @Override
    public boolean equals(OverrideExample obj) {
    return false;
    }
    }
    

     

    然而,當(dāng)您編譯 OverrideExample.java 時,您將得到一個錯誤,該錯誤指示一個細(xì)微的問題。

    % javac OverrideExample.java
    javac OverrideExample.java
    OverrideExample.java:3: method does not override a method from its superclass
    @Override
    ^
    1 error
    

     

    通過提示編譯器您希望進(jìn)行覆蓋,使編譯器能夠捕獲到 equals() 方法帶 Object 類型參數(shù)的細(xì)微 bug。

    @Override 批注在實際中有用嗎?只有當(dāng)您是一個愿意用 @Override 來標(biāo)記每一個覆蓋方法的非常嚴(yán)謹(jǐn)?shù)木幊倘藛T時才有用。我們中有多少人能聲稱可以達(dá)到這種嚴(yán)謹(jǐn)程度?我認(rèn)為我不能。可能 IDE 將找到一種方式來鼓勵或強(qiáng)制使用 @Override

    @Deprecated

    第二種標(biāo)準(zhǔn)批注是 @Deprecated,它與 @deprecated Javadoc 標(biāo)記有幾乎相同的行為。您可以用類似以下的方式來使用它:

    public class DeprecatedExample {
    @Deprecated
    public static void badMethod() {
    }
    }
    public class DeprecatedUser {
    public static void main(String[] args) {
    DeprecatedExample.badMethod();
    }
    }
    

     

    The @Deprecated 批注看起來非常像 @deprecated 標(biāo)記,除了它出現(xiàn)在注釋外面的方法或類聲明的前面,并且有一個大寫字母 "D"。如果您試圖編譯上面的代碼,javac 將產(chǎn)生警告:

    % javac Deprecated*.java
    Note:DeprecatedUser.java uses or overrides a deprecated API.
    Note:Recompile with -Xlint:deprecation for details.
    1 error
    

     

    如果您遵循警告的建議并用 -Xlint:deprecation 進(jìn)行編譯,那么您將得到關(guān)于警告的詳細(xì)信息:

    % javac -Xlint:deprecation
    DeprecatedUser.java:3: warning: [deprecation] badMethod() in DeprecatedExample
    has been deprecated
    DeprecatedExample.badMethod();
    

     

    @Deprecated 批注比 @Override 更有用嗎?我不這么認(rèn)為。該批注不支持任何參數(shù),因此與 Javadoc 標(biāo)記不同,您不能提供一個字符串來說明不贊成使用該方法并推薦一個替代的方法進(jìn)行使用。@Deprecated 批注提供的價值實際上比 @deprecated 標(biāo)記少。該批注唯一的優(yōu)勢是您可以通過編程的方式在運行時檢測不贊成使用的項目。因此,傳統(tǒng)觀點認(rèn)為應(yīng)當(dāng)同時使用 @deprecated 標(biāo)記和 @Deprecated 標(biāo)記,一個用于文檔,另一個用于運行時反射。

    我覺得很不幸 JSR-175 沒有選擇對 @Deprecated 做更多的工作。至少該批注應(yīng)當(dāng)復(fù)制 @deprecated 標(biāo)記的功能,包含一個字符串說明,從而編譯器可以將其與“不贊成使用” (Deprecation) 警告一起輸出。利用額外的參數(shù),@Deprecated 還可以接收 "isError" 布爾類型參數(shù),以指示是否完全不鼓勵使用該方法或者使用它將被認(rèn)為是編譯錯誤(利用解釋錯誤原因的清楚的自定義說明來進(jìn)行完善)。查看 C# 的示例 1 找到屬性 [Obsolete],該屬性正好實現(xiàn)了這一點,它被證明非常有用。

    @SuppressWarnings

    J2SE 提供的最后一個批注是 @SuppressWarnings。該批注的作用是給編譯器一條指令,告訴它對被批注的代碼元素內(nèi)部的某些警告保持靜默。

    一點背景:J2SE 5.0 為 Java 語言增加了幾個新的特性,并且和它們一起增加了許多新的警告并承諾在將來增加更多的警告。您可以為 "javac" 增加 -Xlint 參數(shù)來控制是否報告這些警告(如上面的 @Deprecated 部分所示)。

    默認(rèn)情況下,Sun 編譯器以簡單的兩行的形式輸出警告。通過添加 -Xlint:keyword 標(biāo)記(例如 -Xlint:finally),您可以獲得關(guān)鍵字類型錯誤的完整說明。通過在關(guān)鍵字前面添加一個破折號,寫為 -Xlint:-keyword,您可以取消警告。(-Xlint 支持的關(guān)鍵字的完整列表可以在 javac 文檔頁面上找到。)下面是一個清單:

    關(guān)鍵字 用途
    deprecation 使用了不贊成使用的類或方法時的警告
    unchecked 執(zhí)行了未檢查的轉(zhuǎn)換時的警告,例如當(dāng)使用集合時沒有用泛型 (Generics) 來指定集合保存的類型。
    fallthrough 當(dāng) Switch 程序塊直接通往下一種情況而沒有 Break 時的警告。
    path 在類路徑、源文件路徑等中有不存在的路徑時的警告。
    serial 當(dāng)在可序列化的類上缺少 serialVersionUID 定義時的警告。
    finally 任何 finally 子句不能正常完成時的警告。
    all 關(guān)于以上所有情況的警告。

     

    @SuppressWarnings 批注允許您選擇性地取消特定代碼段(即,類或方法)中的警告。其中的想法是當(dāng)您看到警告時,您將調(diào)查它,如果您確定它不是問題,您就可以添加一個 @SuppressWarnings 批注,以使您不會再看到警告。雖然它聽起來似乎會屏蔽潛在的錯誤,但實際上它將提高代碼安全性,因為它將防止您對警告無動于衷 — 您看到的每一個警告都將值得注意。

    下面是使用 @SuppressWarnings 來取消 deprecation 警告的一個例子:

    public class DeprecatedExample2 {
    @Deprecated
    public static void foo() {
    }
    }
    public class DeprecatedUser2 {
    @SuppressWarnings(value={"deprecation"})
    public static void main(String[] args) {
    DeprecatedExample2.foo();
    }
    }
    

     

    @SuppressWarnings 批注接收一個 "value" 變量,該變量是一個字符串?dāng)?shù)組,它指示將取消的警告。合法字符串的集合隨編譯器而變化,但在 JDK 上,可以傳遞給 -Xlint 的是相同的關(guān)鍵字集合(非常方便)。并且要求編譯器忽略任何它們不能識別的關(guān)鍵字,這在您使用一些不同的編譯器時非常方便。

    因為 @SuppressWarnings 批注僅接收一個參數(shù),并為該參數(shù)使用了特殊的名稱 "value",所以您可以選擇省略 value=,作為一種方便的縮寫:

    public class DeprecatedUser2 {
      @SuppressWarnings({"deprecation"})
    public static void main(String[] args) {
        DeprecatedExample2.foo();
      }
    }

    您可以將單個數(shù)組參數(shù)中的任意數(shù)量的字符串值傳遞給批注,并在任何級別上放置批注。例如,以下示例代碼指示將取消整個類的 deprecation 警告,而僅在 main() 方法代碼內(nèi)取消 unchecked 和 fallthrough 警告:

    import java.util.*;

    @SuppressWarnings({"deprecation"})
    public class NonGenerics {

      @SuppressWarnings({"unchecked","fallthrough"})
    public static void main(String[] args) {
        Runtime.runFinalizersOnExit();

        List list = new ArrayList();
        list.add("foo");
      }

      public static void foo() {
        List list = new ArrayList();
        list.add("foo");
      }
    }

    @SuppressWarnings 是否比前兩個批注更有用?絕對是這樣。不過,在 JDK 1.5.0 版本中還沒有完全支持該批注,如果您用 1.5.0 來嘗試它,那么它將類似無操作指令。調(diào)用 -Xlint:-deprecation 也沒有任何效果。Sun 沒有聲明什么時候?qū)⒃黾又С郑凳具@將在即將推出的一個 dot 版本中實現(xiàn)。

    posted on 2008-10-01 14:12 afunms 閱讀(269) 評論(0)  編輯  收藏


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     

    My Links

    News

    留言簿(18)

    隨筆檔案

    相冊

    搜索

    最新評論

    閱讀排行榜

    主站蜘蛛池模板: 精品国产_亚洲人成在线| 亚洲欧美自偷自拍另类视| 一级白嫩美女毛片免费| 在线永久免费观看黄网站| 国产精品亚洲专区在线观看 | 亚洲精品白色在线发布| 久久久高清日本道免费观看| 亚洲Av综合色区无码专区桃色| 中文字幕一区二区免费| 亚洲va中文字幕无码久久| 91视频免费网址| 亚洲精品天堂在线观看| 国产午夜免费福利红片| 一级特黄录像视频免费| 亚洲日韩v无码中文字幕| 一级毛片免费观看不卡的| 亚洲精品在线不卡| 成人免费毛片内射美女APP| 亚洲av无码一区二区三区四区 | 亚洲一区二区三区免费在线观看| 亚洲日韩乱码久久久久久| 67194成是人免费无码| 免费国产a理论片| 久久精品国产亚洲网站| 亚洲人成免费电影| 在线观看亚洲AV日韩A∨| 亚洲阿v天堂在线2017免费| 免费一区二区三区| 亚洲色欲色欲www| 亚洲AV中文无码乱人伦| 一区二区三区四区免费视频 | 一级做a爰全过程免费视频| 国产 亚洲 中文在线 字幕| 亚洲va中文字幕无码| 一区二区三区观看免费中文视频在线播放 | 亚洲国产成人无码av在线播放| 日本免费一区尤物| 青青操在线免费观看| 久久亚洲精品专区蓝色区| 久久久久亚洲AV成人网| 男女做羞羞的事视频免费观看无遮挡 |