很多Java程式設計師,對Java的註解一知半解,更有甚者,有的人可能連註解是什麼都不知道

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

先來簡單回顧一下基礎,我們知道,Java 的原始檔編輯後,生成 .class 檔案,

  1. .Java原始檔,這個是原始檔時期
  2. 原始檔經過編譯生成 .class 位元組碼檔案,這個也是編譯時期
  3. .class 載入到記憶體中,就可以用了,這個是執行期間

如下圖

記住以上知識點,下面和註解有關,我們正式來講註解

本文將從以下 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軟體又是用什麼開發的?

定義一個註解,用元註解

是不是很類似,如下圖

看過上面的圖應該能理解了,什麼是元註解了吧,就是為了定義註解用的,知道怎麼用就行了

就比如我們開發軟體,要用到各種各樣的開發軟體的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 站長 我的職位是:工程師 我的評價是:工作很努力

本文到此,幾乎講完了,註解的很多其它的東西還沒有講,不過不重要,本文最重要的讓你明白什麼是註解,怎麼定義註解,怎麼使用註解

至於註解其它的知識,比如註解怎麼用在方法上,用上類上,等等,都是類似,只需要查一下就行了。

網上很多文章 ,只要能通過本文把註解弄明白了,瞭解註解其它的就簡單了。