本博文是對(duì)Java中注解相關(guān)知識(shí)點(diǎn)的簡(jiǎn)單總結(jié),,若有敘述不清晰或是不準(zhǔn)確的地方,希望大家可以指正,,謝謝大家:) 一,、什么是注解 我們大家都知道Java代碼中使用注釋是為了向以后閱讀這份代碼的人解釋說(shuō)明一些事情,注解是注釋的升級(jí)版,,它可以向編譯器,、虛擬機(jī)等解釋說(shuō)明一些事情。比如我們非常熟悉的@Override就是一種元注解,,它的作用是告訴編譯器它所注解的方法是重寫(xiě)父類的方法,,這樣編譯器就會(huì)去檢查父類是否存在這個(gè)方法,以及這個(gè)方法的簽名與父類是否相同,。 也就是說(shuō),,注解是描述Java代碼的代碼,它能夠被編譯器解析,,注解處理工具在運(yùn)行時(shí)也能夠解析注解,。我們?cè)贘ava源文件中使用注釋,是為了以后我們或他人再來(lái)讀這段代碼時(shí),,能夠更好地理解它,。Javadoc工具可以解析我們?cè)?span>源代碼中為類、方法,、變量等添加的描述信息,,并根據(jù)這些描述信息自動(dòng)生成一個(gè)HTML文檔,這些自動(dòng)生成的文檔即可作為API幫助文檔,。只要我們?yōu)轭?、方法等添加的描述信息符?span>Javadoc要求的語(yǔ)法,我們就能夠使用Javadoc工具根據(jù)我們的描述信息自動(dòng)生成一個(gè)幫助文檔,。而注解比java注釋和Javadoc要強(qiáng)大得多,,它們?nèi)咧g的重大的區(qū)別在于,Java注釋和Javadoc描述所發(fā)揮的作用僅僅到編譯時(shí)就止步了,,而注解直到運(yùn)行時(shí)都能夠發(fā)揮作用,。 我們知道,使用“transient”關(guān)鍵字可以告訴編譯器這個(gè)域不可序列化,。相比于用”transient“這樣的關(guān)鍵字修飾一個(gè)屬性,,注解為我們提供了為類/方法/屬性/變量添加描述信息的更通用的方式,,而這些描述信息對(duì)于開(kāi)發(fā)者、自動(dòng)化工具,、Java編譯器和Java運(yùn)行時(shí)來(lái)說(shuō)都是有意義的,,也就是說(shuō)他們都能“讀懂”注解信息?!?span>transient“關(guān)鍵字是一個(gè)修飾符,,而注解也是一種修飾符。除了傳遞信息,,我們也可以使用注解生成代碼,。我們可以使用注解,然后讓注解解析工具來(lái)解析它們,,以此來(lái)生成一些”模板化“的代碼,。比如Hibernate、Spring,、Axis這些框架大量使用了注解,,來(lái)避免一些重復(fù)的工作。 二,、元注解 元注解即用來(lái)描述注解的注解,,比如以下代碼中我們使用“@Target”元注解來(lái)說(shuō)明MethodInfo這個(gè)注解只能應(yīng)用于對(duì)方法進(jìn)行注解: @Target(ElementType.METHOD) public @interface MethodInfo { ... } 下面我們來(lái)具體介紹一下幾種元注解。 1. Documented 當(dāng)一個(gè)注解類型被@Documented元注解所描述時(shí),,那么無(wú)論在哪里使用這個(gè)注解,,都會(huì)被Javadoc工具文檔化。我們來(lái)看一下它的定義: @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Documented { } 我們從以上代碼中可以看到,,定義注解使用@interface關(guān)鍵字,,這就好比我們定義類時(shí)使用class關(guān)鍵字,定義接口時(shí)使用interface關(guān)鍵字一樣,,注解也是一種類型,。這個(gè)元注解被@Documented修飾,表示它本身也會(huì)被文檔化,。@Retention元注解的值RetentionPolicy.RUNTIME表示@Documented這個(gè)注解能保留到運(yùn)行時(shí),;@Target元注解的值ElementType.ANNOTATION_TYPE表示@Documented這個(gè)注解只能夠用來(lái)描述注解類型。 2. Inherited 表明被修飾的注解類型是自動(dòng)繼承的,。具體解釋如下:若一個(gè)注解類型被Inherited元注解所修飾,,則當(dāng)用戶在一個(gè)類聲明中查詢?cè)撟⒔忸愋蜁r(shí),若發(fā)現(xiàn)這個(gè)類聲明中不包含這個(gè)注解類型,,則會(huì)自動(dòng)在這個(gè)類的父類中查詢相應(yīng)的注解類型,,這個(gè)過(guò)程會(huì)被重復(fù),直到該注解類型被找到或是查找完了Object類還未找到,。這個(gè)元注解的定義如下: @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Inherited { } 我們可以看到這個(gè)元注解類型被@Documented所注解,,能夠保留到運(yùn)行時(shí),只能用來(lái)描述注解類型,。 3. Retention 我們?cè)谏厦嬉呀?jīng)見(jiàn)到個(gè)這個(gè)元注解,,它表示一個(gè)注解類型會(huì)被保留到什么時(shí)候,比如以下代碼表示Developer注解會(huì)被保留到運(yùn)行時(shí): @Retention(RetentionPolicy.RUNTIME) public @interface Developer { String value; } @Retention元注解的定義如下: @Documented @Target(ElementType.ANNOTATION_TYPE) public @interface Retention { RetentionPolicy value; } 我們?cè)谑褂聾Retention時(shí),,后面括號(hào)里的內(nèi)容即表示他的取值,,從以上定義我們可以看到,取值的類型為RetentionPolicy,,這是一個(gè)枚舉類型,,它可以取以下值: SOURCE:表示在編譯時(shí)這個(gè)注解會(huì)被移除,不會(huì)包含在編譯后產(chǎn)生的class文件中,; CLASS:表示這個(gè)注解會(huì)被包含在class文件中,,但在運(yùn)行時(shí)會(huì)被移除; RUNTIME:表示這個(gè)注解會(huì)被保留到運(yùn)行時(shí),,在運(yùn)行時(shí)可以JVM訪問(wèn)到,,我們可以在運(yùn)行時(shí)通過(guò)反射解析這個(gè)注解。 4. Target 這個(gè)元注解說(shuō)明了被修飾的注解的應(yīng)用范圍,,也就是被修飾的注解可以用來(lái)注解哪些程序元素,,它的定義如下: @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.ANNOTATION_TYPE) public @interface Target { ElementType value; } 從以上定義我們可以看到它也會(huì)保留到運(yùn)行時(shí),而且它的取值是為ElementType類型(一個(gè)數(shù)組,,意思是可以指定多個(gè)值),,ElementType是一個(gè)枚舉類型,它可以取以下值: TYPE:表示可以用來(lái)注解類,、接口,、注解類型或枚舉類型; PACKAGE:可以用來(lái)注解包,; PARAMETER:可以用來(lái)注解參數(shù),; ANNOTATION_TYPE:可以用來(lái)注解 注解類型; METHOD:可以用來(lái)注解方法,; FIELD:可以用來(lái)注解屬性(包括枚舉常量),; CONSTRUCTOR:可以用來(lái)注解構(gòu)造器; LOCAL_VARIABLE:可用來(lái)注解局部變量,。 三,、常見(jiàn)內(nèi)建注解 Java本身內(nèi)建了一些注解,下面我們來(lái)介紹一下我們?cè)谌粘i_(kāi)發(fā)中比較常見(jiàn)的注解:@Override,、@Deprecated,、@SuppressWarnings。相信我們大家或多或少都使用過(guò)這三個(gè)注解,,下面我們一起再重新認(rèn)識(shí)一下它們,。 1. @Override注解 我們先來(lái)看一下這個(gè)注解類型的定義: @Target(ElementType.METHOD) @Retention(RetentionPolicy.SOURCE) public @interface Override { } 從它的定義我們可以看到,,這個(gè)注解可以被用來(lái)修飾方法,并且它只在編譯時(shí)有效,,在編譯后的class文件中便不再存在,。這個(gè)注解的作用我們大家都不陌生,那就是告訴編譯器被修飾的方法是重寫(xiě)的父類的中的相同簽名的方法,,編譯器會(huì)對(duì)此做出檢查,,若發(fā)現(xiàn)父類中不存在這個(gè)方法或是存在的方法簽名不同,則會(huì)報(bào)錯(cuò),。
|
|