注解——體系篇

一、前言

本文分析注解體系的主要目的有如下三點:

  1. 個人的知識體系的梳理,希望能把書由薄讀厚,再由厚讀??;
  2. 為后續(xù)博文,仿ButterKnife框架的內(nèi)容鋪墊;
  3. ORM類型框架中大量使用到了注解的內(nèi)容,明確注解意義及使用方法,能夠打通學(xué)習(xí)ORM類型框架的任督二脈。

進入正題:

  • 用專業(yè)名詞解釋專業(yè)名詞的注解說明版本如下:
  • 個人認為這樣去理解適合于有經(jīng)驗的開發(fā)同學(xué)。

    從JDK5開始,Java增加了對元數(shù)據(jù)(MetaData)的支持,也就是Annotation(即注解),這里介紹的注解,其實是代碼里的特殊標記,這些標記可以在編譯、類加載。運行時被讀取,并執(zhí)行相應(yīng)的處理。通過使用注解,程序開發(fā)人員可以在不改變原有邏輯的情況下,在源文件中嵌入一些補充的信息。代碼分析工具、開發(fā)工具和部署工具可以通過改變這些補充信息進行驗證或者進行部署。 ———《瘋狂Java講義》

  • 對于新手同學(xué),我建議查看frank909的《秒懂,Java 注解(Annotation)你可以這樣學(xué)》戳→文章傳送門。

圖1 注解體系結(jié)構(gòu)圖

二、注解體系

1、注解概述

注解提供了一種為程序元素設(shè)置元數(shù)據(jù)的方法,從某些方面來看,注解就像修飾符一樣,可以用于修飾包、類、構(gòu)造器、方法、成員變量、參數(shù)、局部變量的聲明,這些信息被儲存在注解的“name=value”對中。

注解能被用來為程序元素(類、方法、成員變量)設(shè)置元數(shù)據(jù)。值得指出的是,注解不影響程序代碼的執(zhí)行,無論添加、刪除注解,代碼都始終如一的執(zhí)行。如果希望讓程序中的注解在運行時起一定的作用,只有通過某種配套的工具對注解中的信息進行訪問和處理,訪問和處理注解的工具統(tǒng)稱為APT(Annotation Processing Tool)。

1.1 元數(shù)據(jù)(metadata)

元數(shù)據(jù)(metadata):就是關(guān)于數(shù)據(jù)的數(shù)據(jù)。

  • 示例:
    ①表格中呈現(xiàn)的是數(shù)據(jù),而表格還會有額外的數(shù)據(jù)來說明表格的作用,這個就是表格的元數(shù)據(jù)。
    ②數(shù)據(jù)庫中的表存放了數(shù)據(jù),但表還需要有表的定義、字段的定義等,這個就是數(shù)據(jù)庫表的元數(shù)據(jù)。
    ③XML文件可以存放數(shù)據(jù)。但xml文件的每個標簽還需要有相應(yīng)的描述,這些描述就是XML標簽的元數(shù)據(jù)。
  • 元數(shù)據(jù)可以用于創(chuàng)建文檔,跟蹤代碼中的依賴性,甚至執(zhí)行基本編譯時檢查。

1.2 什么是Annotation

  • JDK5.0通過名為Annotation(注解)的新功能將一個更通用的元數(shù)據(jù)工具合并到核心 Java 語言中。
  • 注解是可以添加到代碼中的修飾符,對程序代碼做出一些說明和解釋??梢杂糜诎暶?、類聲明、構(gòu)造方法、方法、字段、參數(shù)和變量。
    這樣就將程序的元素和元數(shù)據(jù)聯(lián)系起來。編譯器就可以將元數(shù)據(jù)存儲在Class文件中。之后虛擬機和其它對象可以根據(jù)這些元數(shù)據(jù)來決定如何使用這些程序元素或改變它們的行為。
  • JDK5.0包含了內(nèi)置注解,還支持編寫定制注解。

1.3 注解基本知識

  • 注解采用“@”標記形式 ,后面跟注解類型名稱。通過(name=value)向注解提供參數(shù)數(shù)據(jù)。每次使用這類表示法時,就是在生成注解。
    注解類型和注解的區(qū)別:注解類型類似于類,注解類似于該類的實例

2、內(nèi)置注解類型

2.1 內(nèi)置注解類型—Override

  • Override 指明被注解的方法必須是重寫超類中的方法。僅能用于方法之上。
    編譯器在編譯源代碼時會檢查用@Override標注的方法是否有重寫父類的方法。
    舉例如下:
public class InternalAnnotationTest {
    @Override
    public String toString() {
        return super.toString() + " [Override toString]";
    }

    public static void main(String[] args) {
        TestAnnotation test = new TestAnnotation();
        System.out.println(test);
    }
}

2.2 內(nèi)置注解類型—Deprecated

  • Deprecated 指明被注解的方法為過時的方法,不建議使用了。能用于方法之上。
    當編譯調(diào)用到被標注為Deprecated的方法的類時,編譯器會產(chǎn)生警告。
    舉例如下:
public class InternalAnnotationTest {
    …
    @Deprecated
    public void test(){
        System.out.println("[Deprecated Annotation]");
    }
}

2.3 內(nèi)置注解類型—SuppressWarnings

  • SuppressWarnings 指明被注解的方法在編譯時如果有警告信息,就阻止警告??煞胖萌魏挝恢?。
  • 它有一個必需屬性:value,是String[]類型的,指定取消顯示的警告集。警告類型如下:
類型 作用
unused 未被使用的警告
deprecation 使用了不贊成使用的類或方法時的警告
unchecked 執(zhí)行了未檢查的轉(zhuǎn)換時的警告
rawtypes 沒有用泛型 (Generics) 的警告
fallthrough 當 Switch 程序塊直接通往下一種情況而沒有 Break 時的警告。
path 在類路徑、源文件路徑等中有不存在的路徑時的警告。
serial 當在可序列化的類上缺少 serialVersionUID 定義時的警告。
finally 任何 finally 子句不能正常完成時的警告。
all 關(guān)于以上所有情況的警告。

舉例如下:

public class InternalAnnotationTest {
@SuppressWarnings(value={"unchecked", "deprecation"})
    public void test() {
        Map map = new HashMap();
        map.put("name", "Alex");
        System.out.println(map);
    }
}

3、自定義注解類型

格式如下:

[訪問修飾符] @interface 注解類型名 {
     數(shù)據(jù)類型 屬性名() [default 默認值];//定義屬性
}

舉例如下:

public @interface AlexDebug{
}

public @interface AlexAnnotation{
    String value();
}

public @interfacle AlexType{
    int age() default 18;
}

4、元注解

元注解:對注解的注解

  • 為注解類型提供某種元數(shù)據(jù),使用系統(tǒng)預(yù)定義的元注解可以對我們的注解進行注解。
    結(jié)合元注解,我們可以對自定義注解類型進行相當大程度的內(nèi)容補充說明。

Java的API為我們提供的元注解如下:

4.1 @Target

指定此注解的適用時機

  • 在定義注解類型時,使用java.lang.annotation.Target可以定義其適用的時機。
    在定義時要指定為java.lang.annation.ElementType的枚舉值之一:
package java.lang.annotation;

public enum ElementType{
    TYPE,                         //適用于 類,接口,枚舉
    FIELD,                        //適用于 成員字段
    METHOD,                       //適用于 方法
    PARAMETER,                    //適用于 方法的參數(shù)
    CONSTRUCTOR,                 //適用于 構(gòu)造方法
    LOCAL_VARIABLE,              //適用于 局部變量
    ANNOTATION_TYPE,            //適用于 注解類型
    PACKAGE                   //適用于 包
}

舉例如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Target;

//聲明注解適用于方法
@Target({ElementType.METHOD})
public @interface AlexAnnotation {
}

4.2 @Retention

  • 使用java.lang.annotation.Retention用來告訴編譯器如何處理當前注解。
    在使用Retention類型時,需要提供java.lang.annotation.RetentionPolicy的枚舉類型,它的定義如下:
package java.lang.annotation;

public enum RetentionPolicy {
    SOURCE,      //編譯器處理完后,并不將它保留到編譯后的類文件中
    CLASS,         //編譯器將注解保留在編譯后的類文件中,但是在運行時忽略它
    RUNTIME     //編譯器將注解保留在編譯后的類文件中,并在第一次加載類時讀取它
}

內(nèi)置注解中的Override、SuppressWarnings的RetentionPolicy為SOURCE,而Deprecated為RUNTIME

4.3 @Documented

  • 在默認情況下,注解不包括在Javadoc 中,用java.lang.annatation.Documented可以使此注解加入到Javadoc中。
  • 定義為Documented的注解必須要設(shè)置Retention的值為RetentionPolicy.RUNTIME。
    舉例如下:
import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Documented
@Retention(RetentionPolicy.RUNTIME)
public @interface DocAnnotation {
}

4.5 @Inherited

  • 定義的注解類型使用于程序代碼上后,默認父類中的注解并不會繼承至子類中。
    如果想讓父類中的注解被繼承到子類中,可以在定義注解類型時加上java.lang.annotation.Inherited類型的注解。

舉例如下:

@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface Alex{
    String name();
    int value();
}

@Alex(name="John Snow",age=32)
public class Parent{}

class SubClass extends Parent{}

4.6 @Repeatable

  • 意味著注解的值可以同時取多個
    @Repeatable是Java1.8加進來的新注解,同樣這里我們舉個例子:
@interface Persons {
    Person[] value();
}

@Repeatable(Persons.class)
@interface HumanBeing{
    String role default "coder";
}


@Person(role="PM")
@Person(role="Teacher")
@Person(role="Reader")
public class Alex{
    
}

三、結(jié)語

1、一個技術(shù)開發(fā)人員老去的標志,絕不是老成穩(wěn)重、沉默寡言,而是不肯再嘗試,不肯再容許自己置身不熟悉的境地。
2、一個技術(shù)開發(fā)人員開始廢掉的跡象之二,便是沉溺于短期快感之中,不再做長期投入。不再深入研究底層內(nèi)容。在這里,我對注解相關(guān)的知識體系進行梳理,后續(xù)會推出更多的內(nèi)容和大家分享。
3、一個技術(shù)開發(fā)人員開始廢掉的跡象之三,是淪為抵觸的情緒的奴隸。遇到新技術(shù)畏手畏腳,遇困難而退縮。

希望我們一起努力,加油!

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

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

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