一篇文章通俗易懂的讓你徹底理解 Java 注解


很多Java程序員,對Java的注解一知半解,更有甚者,有的人可能連注解是什么都不知道

本文我們用最簡單的 demo , 最通俗最短的語言,帶你了解注解到底是什么?

先來簡單回顧一下基礎,我們知道,Java 的源文件編輯后,生成 .class 文件,

  1. .Java源文件,這個是源文件時期
  2. 源文件經過編譯生成 .class 字節碼文件,這個也是編譯時期
  3. .class 加載到內存中,就可以用了,這個是運行期間

如下圖
image

記住以上知識點,下面和注解有關,我們正式來講注解
本文將從以下 2 個方面來講解注解

  • 1 注解是什么
  • 2 如何定義一個注解
  • 3 如何使用注解

尤其是第3條,很多人不理解注解,就是因為不知道如何使用注解
3條本文會用最簡單的語言來揭示如何使用

一 注解是什么?

一句話,注解就和生活中的標簽一樣,比如一個人,這個人可能有 學生標簽,月光族標簽,愛抬杠標簽

二 如何定義一個注解

語法: public @interface 注解名 { }
對的, @interface 是個關鍵字,記住就行了,沒有為什么
定義注解就是用@interface ,后面跟上注解名

比如定義一個名字叫 info 的注解,如下
新建一個文件 info.java,代碼如下:

package com.demo;

//定義了一個叫做 info 的注解
public @interface info {

}

很簡單吧,上面就定義了一個叫做 info 的注解,下面有2個問題來了

  • 第一個: info 注解用在什么地方?
    是用到類名上? 還是用在 類的字段上 ? 還是用在類的方法上 ?

  • 第二個:info 注解生命周期(或叫保留策略,我更喜歡叫生命周期)
    注解還有生命周期嗎?答案是當然有了

    前面說過,注解類似標簽,一個人可能剛畢業,有月光族標簽,剛畢業賺的少嘛
    但是有可能過了 3,4 年,技術好了,工資漲上去了,可能就沒有月光族標簽了

    那么標簽有幾個生命周期呢?就是本文開頭講的,參考上面的圖
    答案是:3 個 ,分別是 源文件期編譯期運行期

就是說:有的注解存在於源文件期,有的標簽存在於編譯期,有的標簽存在於運行期

::: tip
運行期的注解用的最多,本文着重講運行期間,源文件期,編譯期比較簡單
看懂運行期后,可自行學習另外2個

運行期,也就是注解在運行期還存在
:::

我們接下來給 info 注解定義用在類的字段上,並且是存在於運行期間

先上代碼,再解釋,代碼如下:

@Target(ElementType.FIELD)          //注解作用在類的字段上
@Retention(RetentionPolicy.RUNTIME) //注解存在於運行期
public @interface info {
    
}

由上面代碼可以看到,出現了 @Target , @Retention 注解,那么 @Target , @Retention又是什么?
答:@Target, @Retention 是元注解,咋又出來一個元注解,可以望文生義:元就是元始的意思,最開始的意思
舉個很簡單的例子來幫助了解元注解是什么

比如開發一款 IOS APP 軟件,用 xcode 這個軟件開發,那么 xcode軟件又是用什么開發的?
定義一個注解,用元注解
是不是很類似,如下圖
image

看過上面的圖應該能理解了,什么是元注解了吧,就是為了定義注解用的,知道怎么用就行了
就比如我們開發軟件,要用到各種各樣的開發軟件的IDE,我們不用管這些IDE軟件是哪個軟件開發的
我們只需要知道,元注解就相當於IDE,注解就相當於我們開發的軟件,就OK了

回到上面的info的定義,我們來解釋一下 Target,Retention 這 2 個注解的用處以及能取哪些值

Target 元注解

用處:用來定義注解的用在的地方,比如是用在類上啊,還是用在字段上啊,還是用在方法上啊等
取值:我們列出幾個常用的就行,其它的自行下去查義即可,如下

取值 用在哪
ElementType.TYPE 類或者接口上
ElementType.FIELD 類的字段上
ElementType.METHOD 類的方法上
ElementType.PARAMETER 方法的參數上

Retention 元注解

用處:用來定義注解的生命周期(或叫保留策略,我更喜歡叫生命周期)
取值:就只有3個,如下

取值 存在於哪個時期
RetentionPolicy.SOURCE 源文件期
RetentionPolicy.CLASS 編譯期
RetentionPolicy.RUNTIME 源運行時期

::: tip
元注解都是已經定義好的,我們只管用,只管知道怎么用就行
就是我們自定義一個注解時才用到元注解,取幾個值,定義一下我們的注解用在哪些地方
存在的時期等,僅此而已
:::


通過上面的敘述,我們小小總結一下

  • 注解就是類似標簽一樣的東西
  • 注解定義是用 public @interface 注解名 { }
  • 注解是有使用的地方和生命周期的
  • 注解能用在類上,字段上,方法上,參數上等
  • 元注解就是用來定義注解的,就像 xcode 軟件是用來開發IOS 軟件一樣的邏輯

下面我們來講第三點,也是最重要的一點,我們學會了自定義注解,怎么使用呢?

三 如何使用注解

注解一般是和反射一塊用的,不懂反射的,不懂Java的大Class的,一定要看看下面的2篇文章
一篇文章徹底搞懂Java的大Class到底是什么
一篇文章弄懂 Java 反射的使用

我們來擴展一下上面的 info注解,代碼如下:

@Target(ElementType.FIELD)          //注解作用在類的字段上
@Retention(RetentionPolicy.RUNTIME) //注解存在於運行期
public @interface info {
    String job();       //job屬性
    String comment();   //comment屬性
}

對的,你又看到了注解還能定義屬性,記住,就按照上面的定義就行了。
主要看怎么用

我們定義一個工人類Worker,如下:

//工人類
public class Worker {
    //工人的名字
    public String name;

    //工人簡介方法,打印工作的基本信息
    public void show(){

    }
}

很簡單的一個類,我們在 name 字段上添加我們定義的info注解,如下

public class Worker {

    //注解是能給屬性傳值的,job和comment和info定義中的相呼應,對,屬性就是這樣用的
    @info(job = "工程師",comment = "工作很努力") 
    public String name;

    public void show(){

    }
}

上面我們給 name 字段添加了我們自己定義的注解,並且給注解中傳了工作的職位是:工程師 ,評價是:工作很努力
我們想在show()方法中,打印出工作的名字,職位,和評價

獲取注解中的 job和 comment可以通過反射獲取 ,注意看注釋,如下

public class Worker {

    //注解是能給屬性傳的,job和comment和定義中的相呼應
    @info(job = "工程師",comment = "工作很努力")
    public String name;

    public void show(){
        //1 獲取本類的字節碼
        Class clz = this.getClass();

        //2 獲取類中定義的字段
        Field[] fields = clz.getDeclaredFields();

        //3 遍歷字段,看看哪個字段有info注解
        for (Field field : fields){
            //4 判斷此字段上是否有 info 注解
            info annotation = field.getAnnotation(info.class);

            //5 如果不為 null ,說明 field上有info注解
            if (annotation != null){
                //6 通過info注解,獲取info注解中的 job和comment
                String job = annotation.job();
                String comment = annotation.comment();

                //7 打印出來
                System.out.println("我是:" + this.name + " 我的職位是:" + job + "  我的評價是:" + comment);
            }
        }
    }
}

通過上面可以看出,使用注解步驟如下:

  1. 獲取類的 Class ,也就是類的字節碼
  2. 獲取類的所有字段的字碼碼數組
  3. 遍歷字段
  4. 通過 info annotation = field.getAnnotation(info.class) 獲取字段上對應的注解
  5. 通過注解,獲取注解中傳的值

我們再來寫一個 main 函數,調用上面那段代碼:如下

public class Demo1 {
    public static void main(String[] args){
        Worker worker = new Worker();
        worker.name = "待兔,www.helloworld.net 站長";
        worker.show();
    }
}

打印如下:

我是:待兔,www.helloworld.net 站長 我的職位是:工程師 我的評價是:工作很努力

本文到此,幾乎講完了,注解的很多其它的東西還沒有講,不過不重要,本文最重要的讓你明白什么是注解,怎么定義注解,怎么使用注解
至於注解其它的知識,比如注解怎么用在方法上,用上類上,等等,都是類似,只需要查一下就行了。
網上很多文章 ,只要能通過本文把注解弄明白了,了解注解其它的就簡單了。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM