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

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

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

    隨筆-6  評論-38  文章-40  trackbacks-0

    JDK5.0中注釋(Annotation)的用法

    很多 API 都需要相當數量的樣板代碼,比如,為了編寫一個 JAX-RPC WEB 服務,你需要提供一個接口和一個實現類。如果這個程序已經被加了注釋 Annotations 以說明那個方法需要被遠程調用,那么我們可以一個工具去自動生成這些樣板代碼。

    還有一些 API 需要在程序代碼另外維護一些文件,比如 JavaBean 需要一個 BeanInfo 類, EJB 需要一個部署描述文件。如果我們能夠把這些需要另外維護的文件內容以注釋 Annotation 的方式和代碼放在一起維護,一定會更加方便同時也減少出錯的機會。

    Java 平臺已經有了一些特別的注釋的機制。比如 transient 修飾符就是一個特別的注釋,表明這個字段應該被序列化子系統忽略; @deprecated javadoc 標簽是一個特別的標簽來說明某個方法已經不再被使用了。 JDK5.0 提供了一個讓我們自己定義我們自己注釋的功能,這個功能包含了如何定義注釋類型的語法,聲明注釋的語法,讀取注釋的 API ,一個類文件保存注釋(譯者注:注釋可以被看作一個類,我們需要用一個 .java 文件保存我們自己定義的注釋源碼)和一個注釋處理的工具。

    注釋并不影響代碼的語義,但卻影響用于處理包含有注釋的程序代碼的工具的處理方式,使他們(工具)能夠影響運行狀態的程序的語義。注釋可以從源代碼中讀取,從編譯后的 .class 文件中讀取,也可以通過反射機制在運行時讀取。

    注釋是 JavaDoc 標簽的補充。一般情況下,如果我們的主要目標是影響或者產生文檔,那么我們應該使用 JavaDoc ;否則,我們應該使用注釋 Annotations

    一般的應用程序開發人員可能從不需要定義一個注釋類型,但定義我們自己的注釋類型并不復雜。注釋類型的定義跟定義一個接口相似,我們需要在 interface 這個關鍵字前面加上一個 @ 符號。注釋中的每一個方法定義了這個注釋類型的一個元素,注釋中方法的聲明中一定不能包含參數,也不能拋出異常;方法的返回值被限制為簡單類型、 String Class emnus 、注釋,和這些類型的數組。方法可以有一個缺省值。這里是一個注釋類型定義的例子:

    /**
    * Describes the Request-For-Enhancement(RFE) that led
    * to the presence of the annotated API element.
    */
    public @interface RequestForEnhancement {
    ??? int??? id();
    ??? String synopsis();
    ??? String engineer() default '[unassigned]';
    ??? String date();??? default '[unimplemented]';
    }

    一旦定義好了一個注釋類型,你就可以用來作注釋聲明。注釋一中特殊的修飾符,在其他修飾符(比如 public static ,或者 final 等)使用地方都可以使用。按照慣例,注釋應該放在其他修飾符的前面。注釋的聲明用 @ 符號后面跟上這個注釋類型的名字,再后面跟上括號,括號中列出這個注釋中元素 / 方法的 key value 對。值必須是常量。這里是一個例子,使用上面定義的注釋類型:

    				
    						
    								@RequestForEnhancement(
    						
    				
    				
    						??? id?????? = 2868724,
    				
    						??? synopsis = 'Enable time-travel',
    				
    						??? engineer = 'Mr. Peabody',
    				
    						??? date???? = '4/1/3007'
    		
    				)

    				public static void travelThroughTime(Date destination) { ... }
    				
    				
    		
    				沒有元素
    				/
    				方法的注釋被成為標記(
    				marker
    				)注釋類型,例如
    				
    						

    				
    				
    				
    						
    								/**
    						
    				
    		
    				 * Indicates that the specification of the annotated API element

    * is preliminary and subject to change. */
    				

    				public @interface Preliminary { }

    		
    				?

    				標記注釋在使用的時候,其后面的括號可以省略,例如:
    				
    						

    @Preliminary public class TimeTravel { ... }
    				如果注釋中僅包含一個元素,這個元素的名字應該為
    				value
    				,例如:
    				
    				
    				
    						
    								/** 
    						
    				
    				* Associates a copyright notice with the annotated API element. 
    				*/ 
    				public @interface Copyright { String value(); }
    		
    		
    ?
    				如果元素的名字為
    				value
    				,使用這個注釋的時候,元素的名字和等號可以省略,如:
    				
    				
    		
    				
    						
    								@Copyright('2002 Yoyodyne Propulsion Systems') 
    						
    				
    				public class OscillationOverthruster { ... }
    		
    				為了將上面提到的東西結合在一起,我們創建了一個簡單的基于注釋的測試框架。首先我們需要一個標記注釋類型用以說明一個方法是一個測試方法,并被測試工具執行。
    				
    						
    								import java.lang.annotation.*;
    						
    				
    		
    				/**

    				 * Indicates that the annotated method is a test method.

    				 * This annotation should be used only on parameterless static methods.

    				 */

    				@Retention(RetentionPolicy.RUNTIME)

    				@Target(ElementType.METHOD)

    				public @interface Test { }

    		

    ?

    我們可以注意到這個注釋類型本省也被注釋了,這種注釋叫做元注釋。第一注釋 (@Retention(RetentionPolicy.RUNTIME)) 表示這種類型的注釋被 VM 保留從而使其能夠通過反射在運行時讀取;第二個注釋 @Target(ElementType.METHOD) 表示這種注釋只能用來注釋方法。

    ?

    下面是一個簡單的類,其中的幾個方法被加了上面的注釋:

    ?

    				
    						
    								public class Foo {

    				
    						??? @Test public static void m1() { }

    				
    						??? public static void m2() { }

    				
    						??? @Test public static void m3() {

    				
    						??????? throw new RuntimeException('Boom');

    				
    						??? }

    				
    						??? public static void m4() { }

    				
    						??? @Test public static void m5() { }

    				
    						??? public static void m6() { }

    				
    						??? @Test public static void m7() {

    				
    						??????? throw new RuntimeException('Crash');

    				
    						??? }

    				
    						??? public static void m8() { }

    				}

    		

    ?

    這里是測試工具:

    ?

    				
    						
    								import java.lang.reflect.*;
    						
    				
    				
    				
    		
    				public class RunTests {

    				
    						?? public static void main(String[] args) throws Exception {

    				
    						????? int passed = 0, failed = 0;

    				
    						????? for (Method m : Class.forName(args[0]).getMethods()) {

    				
    						???????? if (m.isAnnotationPresent(Test.class)) {

    				
    						??????????? try {

    				
    						?????????????? m.invoke(null);

    				
    						?????????????? passed++;

    				
    						??????????? } catch (Throwable ex) {

    				
    						?????????????? System.out.printf('Test %s failed: %s %n', m, ex.getCause());

    				
    						?????????????? failed++;

    				
    						??????????? }

    				
    						???????? }

    				
    						????? }

    				
    						????? System.out.printf('Passed: %d, Failed %d%n', passed, failed);

    				
    						?? }

    				}

    		

    ?

    這個工具用一個類名作為參數,遍歷這個類中的所有方法,并調用其中被加了 @Test 注釋的方法。如果一個方法拋出了一個異常,那么這個測試就失敗了,最終的測試結果被打印了出來。下面是程序運行的結果:

    ?

    				
    						
    								$ java RunTests Foo

    				Test public static void Foo.m3() failed: java.lang.RuntimeException: Boom 

    				Test public static void Foo.m7() failed: java.lang.RuntimeException: Crash 

    				Passed: 2, Failed 2

    		

    ?

    ?

    雖然這個測試工具只是一個玩具,但他顯示了注釋的強大的功能。

    ?

    posted on 2006-11-26 20:04 一手的小窩窩 閱讀(398) 評論(0)  編輯  收藏 所屬分類: JAVA
    主站蜘蛛池模板: wwwxxx亚洲| 亚洲av无码成人黄网站在线观看 | 青青操在线免费观看| 亚洲国产理论片在线播放| 亚洲国产午夜福利在线播放| 免费在线看黄网站| 中美日韩在线网免费毛片视频 | 成全视频免费观看在线看| 亚洲精品精华液一区二区| 亚洲成人激情在线| 亚洲自偷自偷图片| 国产亚洲精品成人a v小说| 国产精品深夜福利免费观看| av无码免费一区二区三区| 波多野结衣免费一区视频| 人人鲁免费播放视频人人香蕉| 亚洲国产精品一区二区三区在线观看| 全免费一级午夜毛片| 色欲A∨无码蜜臀AV免费播| 免费看黄的成人APP| a毛片免费全部播放完整成| 国内精品99亚洲免费高清| 丁香花在线观看免费观看图片| 欧亚一级毛片免费看| 免费的黄色的网站| 免费大片av手机看片| 久久精品国产亚洲Aⅴ蜜臀色欲| 成人免费一级毛片在线播放视频| 亚洲乱码日产一区三区| 亚洲大尺度无码无码专区| 亚洲毛片在线观看| 亚洲国产精品人久久电影| 亚洲国产精品张柏芝在线观看| 亚洲a级片在线观看| 美女扒开屁股让男人桶爽免费| 香蕉免费看一区二区三区| 最近免费中文字幕大全免费版视频| 动漫黄网站免费永久在线观看| 热99re久久免费视精品频软件| 久久99亚洲综合精品首页| 在线免费观看亚洲|