(003)java中的注解(Annotation)

簡(jiǎn)介

注解,java中提供了一種原程序中的元素關(guān)聯(lián)任何信息、任何元素的途徑的途徑和方法。

注解是那些插入到源代碼中使用其他工具可以對(duì)其進(jìn)行處理的標(biāo)簽。注解不會(huì)改變程序的編譯方式。java編譯器會(huì)對(duì)包含注解與不包含注解的代碼生成相同的虛擬機(jī)指令。在java中,注解是被當(dāng)做修飾符(如public/static之類)來(lái)使用的。

概覽圖:

java中的注解概覽圖

注解與注釋

注釋是供人看的,注解是供程序調(diào)用的。一種是程序員寫給另一個(gè)程序員的,一種是程序員寫給計(jì)算機(jī)解析的。

常用注解

  • @Override: 修飾重載父類方法;
  • @Deprecated: 修飾未來(lái)將被拋棄的類/方法/屬性等等;
  • @SuppressWarnings: 關(guān)閉不當(dāng)編譯器警告信息。

注解運(yùn)行機(jī)制分類

  • 源碼注解: 注解只在源碼中存在,編譯成.class文件中不存在;
  • 編譯時(shí)注解: 注解存在于源碼與.class中,運(yùn)行時(shí)不存在;
  • 運(yùn)行時(shí)注解: 在所有階段都存在,可以影響程序運(yùn)行邏輯。

注解來(lái)源分類

  • 來(lái)自jdk的注解:如@Override/@Deprecated等等;
  • 三方的注解: 如junit中的@Test/@Before等等;
  • 自定義注解: 通過(guò)元注解自定義的注解。

元注解

給注解進(jìn)行注解,用于自定義注解。

  • @Target: 指明定義的注解的作用域,其值包括:
    • ElementType.CONSTRUCTOR: 構(gòu)造方法聲明;
    • ElementType.FIELD: 屬性/字段聲明;
    • ElementType.LOCAL_VARIABLE: 局部變量聲明;
    • ElementType.METHOD: 方法聲明;
    • ElementType.PACKAGE: 包聲明;
    • ElementType.PARAMETER: 參數(shù)聲明;
    • ElementType.TYPE: 類接口聲明;
    • ElementType.ANNOTATION_TYPE: 注解類型聲明;
    • ElementType.TYPE_PARAMETER: 類型參數(shù)聲明(@since 1.8);
    • ElementType.TYPE_USE: 類型使用(@since 1.8)
  • @Retention: 自定義注解的生命周期,其值包括:
    • RetentionPolicy.SOURCE: 只在源碼顯示,編譯時(shí)丟棄;
    • RetentionPolicy.CLASS: 編譯時(shí)記錄到.class中,運(yùn)行時(shí)忽略;
    • RetentionPolicy.RUNTIME: 運(yùn)行時(shí)存在,可通過(guò)反射來(lái)讀取。
  • @Inherited: 一個(gè)標(biāo)記注解,闡述了某個(gè)被標(biāo)注的類型是被繼承的,只能繼承與類。
  • @Documented: 用于描述其它類型的annotation應(yīng)該被作為被標(biāo)注的程序成員的公共API,因此可以被例如javadoc此類的工具文檔化。Documented是一個(gè)標(biāo)記注解,沒(méi)有成員。

自定義注解

//@Target(ElementType.METHOD)
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Description {
    String desc() default "";
    String author() default "";
    int age() default 18;
}
  • 使用關(guān)鍵字@interface定義注解;
  • 成員變量以無(wú)參無(wú)異常的方式聲明;
  • 可以通過(guò)default關(guān)鍵字給成員變量指定默認(rèn)值;
  • 成員變量的類型是受限制的,包括原始類型、String、Class、Annotation、Enumeration;
  • 如果注解只有一個(gè)成員變量,則成員名稱必須取名value(),在使用中可以忽略成員名稱與賦值號(hào)(=);
  • 注解可以沒(méi)有成員,沒(méi)有成員的注解稱為標(biāo)示注解。

使用注解

// @<注解名稱>(<成員名1>=<成員值1>,<成員名2>=<成員值2> ...)

@Description(desc = "I'm class annotation")
public class AnnotationApp {

    @Description(desc = "I'm method annotation",author = "rudy")
    public String eyeColor(){
        return "red";
    }
}

解析注解

通過(guò)反射獲取類、方法、成員上的運(yùn)行時(shí)注解信息,從而實(shí)現(xiàn)動(dòng)態(tài)控制程序運(yùn)行的邏輯。

import Annotation.Description;
import org.junit.Test;

public class AnnotationTest {

    @Test
    public void testParse() throws ClassNotFoundException {
        // 取出注解
        Class cls = Class.forName("Annotation.AnnotationApp");
        boolean isExit =  cls.isAnnotationPresent(Description.class);
        if(isExit){
            // 做邏輯處理
            Description annotation = (Description) cls.getAnnotation(Description.class);
            System.out.println("get annotation:" + annotation.desc());
        }else{
            System.out.println("no annotation!");
        }
    }
}
  • 使用類加載器加載類,獲取類對(duì)象;
  • 判斷是否存在類注解;
  • 取出類注解,做邏輯處理;
  • 方法注解類似。

他山之石

都看到這里了,成神之路上,要不要一起?


微信公眾號(hào)rudy_tan_home
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容