這篇文章開始講解java中的註解,在平時的開發當中我相信你或多或少的接觸過註解。比如你可能都見過@override,它代表的就是一個註解。但是,為了更加清晰的去介紹註解,我還是先給出一個例子,讓你能夠方便的理解。
一、認識註解
在平時不知道我們是否都用過便利貼,在一張紙上寫好幾句話,貼在我們需要的地方。就是下面這個;
還有一個情況,大多數人都叫我們程序猿(錢多話少死得快),這也是給我們貼了一個標籤。像這兩種情況基本上就是註解。你可以把這兩種情況聯想到代碼的註解上。比如我們定義了一個方法,這個方法要實現加法的運算,那麼我們就可以定義一個@ADD標籤。表示這個方法就是實現加法的。我們程式設計師一看到這個@ADD,就能很容易理解這個方法是幹嘛的。簡單而言。註解就是對於代碼中某些鮮活個體的貼上去的一張標籤。簡化來講,註解如同一張標籤。
因為,如果你之前還未正式的學習過註解,你就可以把他當成便利貼標籤就好了,這能幫你理解註解的大部分內容。
不過正是開始之前,還是談一下學習註解的主要意義吧。
1、首先我們能夠讀懂別人寫的代碼,特別是框架相關的代碼。
2、本來可能需要很多配置文件,需要很多邏輯才能實現的內容,就可以使用一個或者多個註解來替代,這樣就使得編程更加簡潔,代碼更加清晰。
3、zhuangbility,也就是讓你在面試的時候拿來這個的。
OK,理解了註解的思想,我們就可以正式的學習一下注解了。
二、註解
我們介紹完註解之後在介紹元註解,在上面已經介紹過了,其實註解就是一張便利貼,我們可以隨便寫點東西,貼在我們想貼的地方。下面我們來正式的去介紹一下什麼是註解以及如何定義註解。用法超級簡單。
聲明一個註解,其實和創建一個類差不多,只不過聲明一個類是用class,聲明一個接口是interface。聲明一個註解很簡單,使用@interface。下面我們舉個例子:
簡單吧,但是裡面有一點需要和類、接口的聲明有點不同。註解是沒有方法的,只有成員變量。而且我們可以自己定義默認值。但是形式上和方法一樣.我們使用的時候,就像我們在開發Spring的時候一樣就好了。
三、元註解
元註解是指什麼呢?從名字就可以看出來,元註解就是註解的根,也就是註解的註解。就好對比我們有一堆便利貼,這些便利貼幹什麼的都有,但是我們在定義一個特殊的便利貼,這個特殊的便利貼指的是這些普通的便利貼是幹嘛的。是不是有點亂,沒關係我給你來一張小圖你就明白了
元註解就是註解的註解。明白了吧。對元註解的基本概念了解清楚之後,我們就可以正式的介紹元註解的語法了。
元註解有五種分別是: @Retention、@Documented、@Target、@Inherited、@Repeatable 。
下面我們一一的去介紹一下:
1、@Retention
當 @Retention 應用到一個註解上的時候,它解釋說明了這個註解的存活時間。 它的取值如下:
RetentionPolicy.SOURCE 註解只在源碼階段保留,在編譯器進行編譯時它將被丟棄忽視RetentionPolicy.CLASS 註解只被保留到編譯進行的時候,它並不會被加載到 JVM 中。RetentionPolicy.RUNTIME 註解可以保留到程序運行的時候,它會被加載進入到 JVM 中,所以在程序運行時可以獲取到它們。在代碼中我們如何去使用呢?
2、@Documented
它的作用是能夠將註解中的元素包含到 Javadoc 中去。
3、@Target
,@Target 指定了註解運用的地方。 你可以這樣理解,當一個註解被 @Target 註解時,這個註解就被限定了運用的場景。 類比到標籤,原本標籤是你想張貼到哪個地方就到哪個地方,但是因為 @Target 的存在,它張貼的地方就非常具體了,比如只能張貼到方法上、類上、方法參數上等等。@Target 有下面的取值
ElementType.ANNOTATION_TYPE 可以給一個註解進行註解ElementType.CONSTRUCTOR 可以給構造方法進行註解ElementType.FIELD 可以給屬性進行註解ElementType.LOCAL_VARIABLE 可以給局部變量進行註解ElementType.METHOD 可以給方法進行註解ElementType.PACKAGE 可以給一個包進行註解ElementType.PARAMETER 可以給一個方法內的參數進行註解ElementType.TYPE 可以給一個類型進行註解,比如類、接口、枚舉4、@Inherited
Inherited 是繼承的意思,子類繼承了超類的註解。意思很容易理解。
下面代碼來演示一下他的作用
註解 Test 被 @Inherited 修飾,類 B 繼承 A,類 B 也擁有 Test 這個註解。
5、@Repeatable
@Repeatable是java1.8加進來的,表示的是可重複,就好比一個人有好幾個身份。
下面舉個例子來驗證
四、預置註解
java預置的註解其實還是比較多的,但是我們只要調出幾個比較重要的就好了。
@Deprecated
這個註解是用來標記過時的元素,編譯器在編譯階段遇到這個註解時會發出提醒警告,告訴開發者正在調用一個過時的元素比如過時的方法、過時的類、過時的成員變量。
比如:
這時sayHello()方法上面被一條直線劃了一條,這其實就是編譯器識別後的提醒效果:
@Override
這個註解再熟悉不過了,提示該方法是接口方法的實現或者是子類重寫的父類的方法。
@SuppressWarnings
阻止警告的意思,上面說過調用被@Deprecated註解的方法後,編譯器會警告提醒,而有時候開發者會忽略這種警告,他們可以在調用的地方通過@SuppressWarnings達到目的。
如:
這個時候sayHello()就不會被編譯器處以下劃線的警告了。
@SafeVarargs
參數安全類型註解。它的目的是提醒開發者不要用參數做一些不安全的操作,它的存在會阻止編譯器產生unchecked這樣的警告,它是在Java 1.7的版本中加入的。
如:
上面的代碼中,編譯階段不會報錯,但是運行時會拋出ClassCastException這個異常,所以它雖然告訴開發者要妥善處理,但是開發者自己還是搞砸了。
當然還有很多框架註解,這些註解在我的框架系列的文章會有專門的講解,還請大家支持關注我的微眾,由於系統原因,這裡寫兩句話再給出名字,java的架構師技術棧。謝謝支持
五、獲取註解
也就是我們通過反射獲取類 、函數或成員上的運行時註解信息,從而實現動態控制程序運行的邏輯。舉個例子,看看我們如何通過反射來控制程序運行的邏輯。
不過為了防止你沒有反射的基礎,我們還是先簡單的介紹一下反射的原理。
反射可以讓我們在運行時獲取類的屬性,方法,構造方法、父類、接口等信息,通過反射還可以讓我們在運行期實例化對象、調用方法、即使方法或屬性是私有的的也可以通過反射的形式調用。
下面我們使用代碼來演示:
第一步:定義註解
第一個是類的註解
第二個事類中成員變量的註解
第二步:聲明一個用戶類
第三步:使用反射獲取註解
六、註解的使用
我在網上很多篇博客上看到過很多例子,覺得作者給出的例子很容易把一個初學者帶跑偏了,從思想上限制了註解的使用場景。所以為了不帶跑大家,我先給出一個他的好處,你記住這些註解的優點,有需要的時候使用就好了
提供信息給編譯器: 編譯器可以利用註解來探測錯誤和警告信息編譯階段時的處理: 軟體工具可以用來利用註解信息來生成代碼、Html文檔或者做其它相應處理。運行時的處理: 某些註解可以在程序運行的時候接受代碼的提取總結一下,註解就是一個標籤,你也可以當成一個便利貼,在哪使用就看你是否需要這個便利貼了。
謝謝關注支持,如有不對的地方,還請批評指正。