Picses' sky

          Picses' sky
          posts - 43, comments - 29, trackbacks - 0, articles - 24

          J2SE5.0新特性示例---元數(shù)據(jù)(zz)

          Posted on 2007-08-07 13:32 Matthew Chen 閱讀(301) 評(píng)論(2)  編輯  收藏 所屬分類: Java SE

          J2SE 5.0通過(guò)引入注釋(Annotation)的概念添加了對(duì)元數(shù)據(jù)的支持。

          一個(gè)@xxx形式的注釋可以當(dāng)成一個(gè)修飾符來(lái)使用,它可以放在任何一個(gè)修飾符可以出現(xiàn)的地方。public,static,final都是java語(yǔ)言的修飾符,注釋可以寫在它們可以出現(xiàn)的任何地方。

          舉個(gè)例子,可以看下面一段代碼:

          public class AnnotationExample {

              public @Override int hashCode() {

                 return super.hashCode();

              }

          }

           

          在這個(gè)例子中我們使用了一個(gè)java語(yǔ)言API中已經(jīng)有定義的注釋@Override,通過(guò)在方法hashCode()中使用這個(gè)注釋,說(shuō)明了hashCode是一個(gè)覆蓋了父類方法的方法。

          至于注釋的具體含義我們?cè)谝院蟛糠謺?huì)說(shuō)明。

          如果你想使用一個(gè)類,你必須首先找到它的定義,或者你自己對(duì)它進(jìn)行定義。注釋也是需要定義的,隨便在代碼中插入一個(gè)@XXX之類的注釋是不能夠通過(guò)編譯的。

          一個(gè)最簡(jiǎn)單的Annotation定義類似于接口的定義,就象下面的代碼:

          public @interface Info {

          }

           

          正如你所看到的,里面什么都沒(méi)有,但是即使是這樣,我們也可以在程序里使用它:

          public @Info String  information;

           

          這樣的一種什么都沒(méi)有定義的空注釋我們稱為標(biāo)記注釋(marker annotations

          我們可以在其中添加一個(gè)成員的定義:

          public @interface Info {   

               String author();

          }

           

          這里值得注意的一點(diǎn)是,注釋類中方法的定義不能是私有的,如果你不在前面加public關(guān)鍵字,編譯器會(huì)默認(rèn)為它是公有的。

          在添加上author的定義后,原來(lái)那種只寫了一個(gè)@Info的注釋就必須修改了,之后的注釋必須這樣寫:

          public @Info(author="myname")  void afunction() {

          }

           

          一個(gè)注釋的成員可以有默認(rèn)值:

          public @interface Info {   

               String author() default "myname";

          }

           

          使用默認(rèn)值有什么好處呢?我們可以重新這樣寫了:

          public @Info  void afunction() {

          }

           

          在做標(biāo)記時(shí),如果確認(rèn)某個(gè)成員的值和它的默認(rèn)值相同,我們就可以忽略它,而不必顯式地給每個(gè)成員賦值,這樣就減輕了代碼量。

          如果我們添加的這個(gè)成員名字叫做value的話,也就是:

          public @interface Info {   

               String value();

          }

           

          就有了另外一種注釋的用法: 我們可以直接寫出這樣的注釋@Info(“information”),而不必寫@Info(value=”information”),括號(hào)里的值會(huì)自動(dòng)傳遞給value。這樣的一種注釋稱為單一值注釋(Single-value annotations

          一個(gè)注釋可以有很多類型不同的成員,這樣的一種注釋稱為完整注釋(full annotations

          一個(gè)注釋中的成員類型只能夠是原生類型,字符串,Class類型,注釋類型,枚舉類型,或者一維數(shù)組。

          假設(shè)我們現(xiàn)在有一個(gè)注釋定義:

          public @interface Company {

              String value();

          }

           

          現(xiàn)在我們希望定義另外一個(gè)注釋,這個(gè)注釋類型反映了一個(gè)人的信息:

          public @interface Person {

              public enum Gender{MALE,FEMALE};

             

              String name();

              int age();

              Company company();

              Gender gender() default Gender.MALE;

              String description() default "";

          }

           

          在程序代碼中添加這種類型的注釋時(shí)可以這么寫:

          @Person(age=23,name="MyName",gender=Person.Gender.FEMALE, company=@Company("Foo Corporation"))

           

          java.lang包中定義了三種注釋,分別是:

          n         Deprecated:和過(guò)去javadoc@deprecated含義相同

          n         Override:表示方法覆蓋了父類中的方法

          n         SuppressWarnings:使用這個(gè)注釋可以使編譯器忽略特定類型的警告信息

          具體含義可以參照api文檔。

          我們知道,注釋的引入,為java語(yǔ)言添加了元數(shù)據(jù)的表達(dá)方式,而元數(shù)據(jù)就是關(guān)于數(shù)據(jù)的數(shù)據(jù)。在java中,還有關(guān)于注釋的注釋,我們相應(yīng)的稱之為元注釋(meta-annotations

          java中,我們可以使用4種預(yù)先定義的注釋對(duì)注釋定義進(jìn)行注釋,這4種注釋是:

          n         Target:指明注釋可以在哪些代碼段中使用,以避免對(duì)注釋的誤用。

          n         Retention:說(shuō)明編譯器在編譯和運(yùn)行時(shí)是否忽略該種注釋

          n         Documented:說(shuō)明注釋是否出現(xiàn)在Javadoc

          n         Inherited:當(dāng)我們?cè)谝粋€(gè)類中使用了某種注釋,有時(shí)候會(huì)希望將來(lái)它的所有子類中都包含有該種注釋信息,如果在注釋定義中添加了@Inherited,那么這種注釋就會(huì)被調(diào)用者的子類繼承

          當(dāng)我們?cè)谝粋€(gè)類中使用注釋定義了一系列的元數(shù)據(jù)之后,我們應(yīng)該如何獲取這些元數(shù)據(jù)呢?我們通過(guò)下面的例子來(lái)說(shuō)明。

          Annotation的定義仍然使用列出來(lái)的兩個(gè),因?yàn)槲覀冃枰讷@得類文件中的注釋信息,所以必須在注釋定義中添加Retention注釋。

          首先我們定義兩個(gè)注釋,注釋Todo說(shuō)明了還有什么事情需要做:

          import java.lang.annotation.Retention;

          import java.lang.annotation.RetentionPolicy;

           

          @Retention(RetentionPolicy.RUNTIME)

          public @interface Todo {

              String value();

          }

           

          注釋Author說(shuō)明了一個(gè)方法或者類的定義者:

          import java.lang.annotation.Retention;

          import java.lang.annotation.RetentionPolicy;

           

          @Retention(RetentionPolicy.RUNTIME)

          public @interface Author {

              public enum Gender{MALE,FEMALE};

           

              String name();

              String email();

              Gender gender() default Gender.MALE;

          }

           

          然后我們?cè)谝粋€(gè)簡(jiǎn)單的類中添加這兩種類型的注釋:

          public @Todo("delete this class") class Foo {

             

              public void methodA(){}

              public @Author(name="B",email="b@Foo.com") void methodB(){

              }

             

              public @Author(name="A",email="a@Foo.com") String  fieldA;

          }

           

          通過(guò)下面一段代碼我們可以提取相應(yīng)的元數(shù)據(jù):

          import java.lang.reflect.Method;

           

          public class GetAnnotations {

           

              public static void main(String[] args) {

                 try {

                     Class<?> klass=Class.forName(args[0]);

                     if(klass.isAnnotationPresent(Todo.class))

                     {

                        Todo t=klass.getAnnotation(Todo.class);

                        System.out.println(t);

                     }

                     for(Method m:klass.getMethods())

                     {

                        if(m.isAnnotationPresent(Author.class))

                        {

                            Author a=m.getAnnotation(Author.class);

                            System.out.printf("Method:%s,Author:%s%n",m.getName(),a);

                        }

                     }

                 } catch (ClassNotFoundException e) {

                    

                     e.printStackTrace();

                 }

              }

          }

           

           

          使用下面的命令行運(yùn)行程序:

          java GetAnnotations Foo

           

          運(yùn)行結(jié)果如下:

          @Todo(value=delete this class)

          Method:methodB,Author:@Author(gender=MALE, name=B, email=b@Foo.com)

           

           轉(zhuǎn)自:http://www.aygfsteel.com/jayliu/archive/2005/05/12/4209.html

          Feedback

          # re: J2SE5.0新特性示例---元數(shù)據(jù)(zz)  回復(fù)  更多評(píng)論   

          2007-08-10 09:39 by dreamstone
          不錯(cuò),之前只是簡(jiǎn)單用一下deprecated override等功能

          # re: J2SE5.0新特性示例---元數(shù)據(jù)(zz)  回復(fù)  更多評(píng)論   

          2007-11-11 23:25 by 楊愛(ài)友
          注釋一般是用來(lái)給自己開(kāi)發(fā)人員看的,如果沒(méi)有注釋,這個(gè)人離開(kāi)公司別人很難看懂他的代碼,或過(guò)了很長(zhǎng)時(shí)間,連自己都看不懂了,這種目的的話,我想一般用英文就OK了吧。也許有些注釋是用來(lái)生成文檔的,這時(shí)或許有要求用英文注釋吧。哈哈 沒(méi)聽(tīng)說(shuō)過(guò)哪個(gè)公司要求注釋用英文寫。
          主站蜘蛛池模板: 肥城市| 汉沽区| 湟源县| 松滋市| 瑞金市| 齐齐哈尔市| 伊川县| 乌兰察布市| 老河口市| 大关县| 平乡县| 云安县| 盖州市| 安乡县| 精河县| 太谷县| 华容县| 石棉县| 甘泉县| 施甸县| 彭阳县| 麻江县| 绥江县| 潞西市| 井研县| 万州区| 桃源县| 湖北省| 宁国市| 汾西县| 轮台县| 廉江市| 阿城市| 邢台县| 陆丰市| 临漳县| 莱芜市| 改则县| 崇文区| 临澧县| 明星|