Java注解詳解

2.5 注解

2.5.1 注解簡(jiǎn)介

Annotation是Java提供的一種元程序中的元素關(guān)聯(lián)任何信息和元數(shù)據(jù)(metadata)的途徑和方法。Annotation(注解)是一個(gè)接口,程序可以在編譯期通過(guò)AbstractProcessor處理注解元素,或者運(yùn)行期通過(guò)反射來(lái)獲取指定程序元素的Annotation對(duì)象,然后通過(guò)Annotation對(duì)象來(lái)獲取其中的元數(shù)據(jù)。

在Annotation中,成員以無(wú)參數(shù)的方法的形式被聲明,其方法名和返回值定義了該成員的名字和類型。

2.5.2 元注解

在定義自己的注解之前,我們就必須要了解Java為我們提供的元注解和相關(guān)定義注解的語(yǔ)法。元注解的作用就是負(fù)責(zé)注解其他注解,Java定義了4個(gè)標(biāo)準(zhǔn)的meta-annotation類型,它們被用來(lái)提供對(duì)其它annotation類型作說(shuō)明:@Target,@Retention,@Documented,@Inherited,這里我們看一下Target和Retention:

Target

Target說(shuō)明了Annotation所修飾的對(duì)象范圍:Annotation可被用于packages、types(類、接口、枚舉、Annotation類型)、類型成員(方法、構(gòu)造方法、成員變量、枚舉值)、方法參數(shù)和本地變量(如循環(huán)變量、catch參數(shù))。其取值(ElementType)有:

  1. CONSTRUCTOR:用于描述構(gòu)造器
  2. FIELD:用于描述域
  3. LOCAL_VARIABLE:用于描述局部變量
  4. METHOD:用于描述方法
  5. PACKAGE:用于描述包
  6. PARAMETER:用于描述參數(shù)
  7. TYPE:用于描述類、接口(包括注解類型)或enum聲明

Retention

Retention定義了該Annotation被保留的時(shí)間長(zhǎng)短:其取值(RetentionPolicy)有:

  1. SOURCE:在源文件中有效(即源文件保留)
  2. CLASS:在class文件中有效(即class保留)
  3. RUNTIME:在運(yùn)行時(shí)有效(即運(yùn)行時(shí)保留)

2.5.3 自定義注解

使用@interface自定義注解時(shí),自動(dòng)繼承了Annotation接口,由編譯程序自動(dòng)完成其他細(xì)節(jié)。@interface用來(lái)聲明一個(gè)注解,其中的每一個(gè)方法實(shí)際上是聲明了一個(gè)配置參數(shù),方法的名稱就是參數(shù)的名稱,返回值類型就是參數(shù)的類型,返回值類型只能是基本類型、Class、String、enum,Annotation以及以上類型的數(shù)組,可以通過(guò)default來(lái)聲明參數(shù)的默認(rèn)值。簡(jiǎn)單的自定義注解和使用注解實(shí)例:

//定義注解FruitName
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitName {
    String value() default "";
}

//定義注解FruitColor
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FruitColor {
    public enum Color {BLUE, RED, GREEN};
    Color fruitColor() default Color.GREEN;
}

//使用注解FruitName,F(xiàn)ruitColor
public class Apple {
    @FruitName("Apple")
    private String appleName;
    @FruitColor(fruitColor=Color.RED)
    private String appleColor;

    public void setAppleColor(String appleColor) {
        this.appleColor = appleColor;
    }
    public String getAppleColor() {
        return appleColor;
    }


    public void setAppleName(String appleName) {
        this.appleName = appleName;
    }
    public String getAppleName() {
        return appleName;
    }

    public void displayName(){
        System.out.println("水果的名字是:蘋果");
    }
}

注解元素的默認(rèn)值

注解元素必須有確定的值,要么在定義注解的默認(rèn)值中指定,要么在使用注解時(shí)指定,非基本類型的注解元素的值不可為null。因此使用空字符串或0作為默認(rèn)值是一種常用的做法。一般會(huì)定義一些特殊的值,例如空字符串或者負(fù)數(shù),以此表示某個(gè)元素不存在。

2.5.4 注解處理器

使用注解的過(guò)程中,很重要的一部分就是創(chuàng)建注解處理器。根據(jù)Retention的取值,注解處理器可以分為編譯期處理,運(yùn)行期處理。

運(yùn)行期處理

Java擴(kuò)展了反射API,新增了AnnotatedElement接口,該接口代表程序中可以接受注解的程序元素,該接口主要有如下幾個(gè)實(shí)現(xiàn)類:Class、Constructor、Field、Method和Package。AnnotatedElement聲明了以下四個(gè)方法:

  1. <T extends Annotation> T getAnnotation(Class<T> annotationClass): 返回該程序元素上存在的、指定類型的注解。
  2. Annotation[] getAnnotations():返回該程序元素上存在的所有注解。
  3. boolean isAnnotationPresent(Class<?extends Annotation> annotationClass):判斷該程序元素上是否包含指定類型的注解,存在則返回true,否則返回false.
  4. Annotation[] getDeclaredAnnotations():返回直接存在于此元素上的所有注,該方法將忽略繼承的注釋。
    下面看一個(gè)簡(jiǎn)單的注解處理器:
//該例使用上面定義的注解,定義注解處理器
public class FruitInfoProcessor {
    public static void getFruitInfo(Class<?> clazz){
        String strName="fruit name: ";
        String strColor="fruit color: ";

        Field[] fields = clazz.getDeclaredFields();

        for(Field field :fields){
            if(field.isAnnotationPresent(FruitName.class)){
                FruitName fruitName = (FruitName) field.getAnnotation(FruitName.class);
                strName = strName + fruitName.value();
                System.out.println(strName);
            } else if(field.isAnnotationPresent(FruitColor.class)){
                FruitColor fruitColor= (FruitColor) field.getAnnotation(FruitColor.class);
                strColor = strColor + fruitColor.fruitColor().toString();
                System.out.println(strColor);
            }
        }
    }
}

編譯期處理

總結(jié):Java注解的基礎(chǔ)知識(shí)點(diǎn)基本都過(guò)了一遍,最后用下面一張思維導(dǎo)圖總結(jié)

最后編輯于
?著作權(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)容

  • Annotation基礎(chǔ) 1、什么是annotation 官網(wǎng)的解釋: Annotations, a form o...
    大文子_閱讀 468評(píng)論 0 0
  • 本文章涉及代碼已放到github上annotation-study 1.Annotation為何而來(lái) What:A...
    zlcook閱讀 29,735評(píng)論 15 116
  • 什么是注解(Annotation):Annotation(注解)就是Java提供了一種元程序中的元素關(guān)聯(lián)任何信息和...
    九尾喵的薛定諤閱讀 3,397評(píng)論 0 2
  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評(píng)論 19 139
  • 一個(gè)持久的興趣 像一份真愛(ài) 歷久彌堅(jiān) 一見(jiàn)便是兩兩傾心 像一條幽花小路 通向桃源 跬步便是芳草鮮美落英繽紛 像一扇...
    愛(ài)碼愛(ài)自由閱讀 458評(píng)論 0 10

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