用了這么多年的注解,你知道注解是干嘛的嘛?


引言:
最近入職了新公司,前期比較忙,公司的項目用到了很多自定義注解,自定義注解由于是公司架構(gòu)設(shè)計的,所以和同事溝通中發(fā)現(xiàn)很多小伙伴對注解一知半解,晚上在公司加了會班,發(fā)布這篇關(guān)于注解的文章,希望有幫助到你


注解(Annotation),也叫元數(shù)據(jù)。一種代碼級別的說明。它是JDK1.5及以后版本引入的一個特性,與類、 接口、枚舉是在同一個層次。它可以聲明在包、類、字段、方法、局部變量、方法參數(shù)等的前面,用來對這些元素進(jìn)行說明,注釋。


注解可以用來說明程序,給計算機(jī)解釋,并非給開發(fā)人員看的,注解也可以用來被其他程序讀取


注解格式為"@注解名稱",在代碼中存在,可以添加一些參數(shù),如下:
1@SpringBootApplication
2public?class?SpringBootAdminClientApplication?{
3????public?static?void?main(String[]?args)?{
4????????SpringApplication.run(SpringBootAdminClientApplication.class,?args);
5????}
6}
Annotnation在哪里使用?
可以附加在package,class,method,field等上面,相當(dāng)于給他們添加了額外的輔助信息,可以通過反射機(jī)制編程實現(xiàn)對這些元數(shù)據(jù)的訪問
作用分類:
編寫文檔:通過代碼里標(biāo)識的注解生成文檔【生成文檔doc文檔】
代碼分析:通過代碼里標(biāo)識的注解對代碼進(jìn)行分析【使用反射】
編譯檢查:通過代碼里標(biāo)識的注解讓編譯器能夠?qū)崿F(xiàn)基本的編譯檢查【Override】
常見注解:
@author:用來標(biāo)識作者名,eclipse開發(fā)工具默認(rèn)的是系統(tǒng)用戶名。
@since: ?從那個版本開始
@version:用于標(biāo)識對象的版本號,適用范圍:文件、類、方法。
@Override:用來修飾方法聲明,告訴編譯器該方法是重寫父類中的方法,如果父類不存在該方法,則編譯失敗。


自定義注解: 注解本質(zhì)上就是一個接口,該接口默認(rèn)繼承Annotation接口
1public?interface?MyAnno?extends?java.lang.annotation.Annotation?{}
自定義注解
1//?空注解
2public?@interface?Mobai{
3}
含參數(shù)的注解
只能使用Java提供的基本數(shù)據(jù)類型,String可以,Class可以,枚舉類,其他暫未測試,包裝類不可以.自定義類不可以
1public?@interface?Anno02?{
2????//?屬性
3????String?name();
4????double?price()?default?99;
5????String[]?authors();
6
7//????Anno01?abc();?//?注解
8//????WeekDay?w();
9//????Class?p();
10}
11enum?WeekDay?{
12????SUN,?MON
13}
14class?Person?{
15}


只能包含八種基本數(shù)據(jù)類型,String可以,注解,枚舉,Class,或者以上類型的一堆數(shù)組,自定義類不可以
注解可以用來保存數(shù)據(jù)
使用自定義注解格式:
@注解名(屬性名=屬性值, 屬性名=屬性值)
需要注意的是:注解的屬性可以有默認(rèn)值,當(dāng)使用注解時不賦值就使用默認(rèn)值,賦值就按照賦的值
定義注解
1public?@interface?MoBai?{
2????//?名字
3????String?name();
4
5????//?默認(rèn)屬性
6????String?value()?default?"框架師";
7}
使用注解
1public?class?AnnactionTest?{
2
3????@MoBai(name?=?"墨白",value?=?"")
4????public?static?void?main(String[]?args)?{
5????}
6
7????@Test
8????public?void?annTest(){
9????}
10}


當(dāng)注解只有一個屬性,并且屬性名是value時,在使用注解時可以省略屬性名
自定義注解
1public?@interface?MoBai?{
2????String?value();
3}
使用注解
1@MoBai("abc")
2public?class?Demo11?{
3????@MoBai(value?=?"abc")
4????public?static?void?main(String[]?args)?{
5????}
6}

@Target
@Retention
什么是元注解:修飾注解的注解叫做元注解


這個注解默認(rèn)情況下可以放在任意位置,也可以限制注解放在那些位置
@Target(ElementType.TYPE) ? ? ? ? ? 注解只能放在類或者接口上
@Target(ElementType.CONSTRUCTOR) ? ?注解只能放在構(gòu)造方法上
@Target(ElementType.FIELD) ? ? ? ? ?注解只能放在成員變量上
@Target(ElementType.METHOD) ? ? ? ? 注解只能放在成員方法上
@Target(ElementType.LOCAL_VARIABLE) 注解只能放在局部變量上
具體可以看一下源碼,源碼解釋的比較詳細(xì)


這個注解默認(rèn)是存在Class階段,并且限制了注解存活時間;如下
SOURCE = = = = = = = = = = >>CLASS = = = = = = = = = = = = = >>RUNTIME
源代碼階段(.java) = = = = >>編譯 = = = >>.class = = = = = = >>運行
自定義注解
1//@Target(ElementType.TYPE)?//?注解只能放在類或者接口上
2//@Target(ElementType.CONSTRUCTOR)?//?注解只能放在構(gòu)造方法上
3//@Target(ElementType.FIELD)?//?注解只能放在成員變量上
4//@Target(ElementType.METHOD)?//?注解只能放在成員方法上
5//@Target(ElementType.LOCAL_VARIABLE)?//?注解只能放在局部變量上
6@Retention(RetentionPolicy.RUNTIME)
7public?@interface?MoBai?{
8}
使用注解
1@MoBai
2public?class?Demo12?{
3????@MoBai
4????private?String?a;
5
6????@MoBai
7????public?Demo12()?{
8
9????}
10
11????@MoBai
12????public?static?void?main(String[]?args)?{
13????????@MoBai
14????????int?x?=?10;
15????}
16}

什么是注解解析
獲取注解中保存的數(shù)據(jù)
注解解析相關(guān)接口
1AnnotatedElement接口中:
2Annotation?getAnnotation(Class?annotationClass) ?獲取一個注解**
3Annotation[]?getAnnotations()??獲取多個注解
4boolean?isAnnotationPresent(Class?annotationClass)?判斷有沒有指定的注解
注意: Constructor , Field , Method實現(xiàn)了AnnotatedElement接口


注解在誰頭上,就用誰來獲取注解
注解在構(gòu)造方法上,使用Constructor對象獲取注解
注解在成員方法上,使用Method對象獲取注解
注解在成員變量上,使用Field對象獲取注解
使用反射
創(chuàng)建自定義注解
1import?java.lang.annotation.ElementType;
2import?java.lang.annotation.Retention;
3import?java.lang.annotation.RetentionPolicy;
4import?java.lang.annotation.Target;
5/**
6?* Software:IntelliJ IDEA 2020.1 x64
7?*?Author:?MoBai·杰
8?*?[@]Interface:MoBook
9?*?注解描述:?自定義注解
10?*/
11//?限定方法使用
12@Target(ElementType.METHOD)
13//?活到運行時候
14@Retention(RetentionPolicy.RUNTIME)
15public?@interface?MoBook?{
16????String?name();
17
18????double?price();
19
20????String[]?authors();
21}
定義數(shù)據(jù)類使用注解
1/**
2?* Software:IntelliJ IDEA 2020.1 x64
3?*?Author:?MoBai·杰
4?*?ClassName:Book
5?*?類描述:?書籍類
6?*/
7public?class?Book?{
8????@MoBook(name?=?"框架師",?price?=?25.0,?authors?=?"墨白")
9????public?void?sell()?{
10
11????}
12}測試類
1public?class?TestMoBook?{
2????public?static?void?main(String[]?args)?throws?Exception?{
3????????//?1.獲取Class對象
4????????Class?className?=?Class.forName("com.mobai.annion.Book");
5????????//?2.獲取Method對象
6????????Method?method?=?className.getMethod("sell");
7????????//?3.通過method對象獲取注解
8????????Annotation[]?annotations?=?method.getAnnotations();
9????????//?4.遍歷數(shù)組
10????????for?(Annotation?annotation?:?annotations)?{
11????????????System.out.println("annotation?=?"?+?annotation);
12????????}
13????????//?3.3?boolean?isAnnotationPresent(Class?annotationClass)
14????????//??判斷有沒有指定的注解
15????????boolean?b?=?method.isAnnotationPresent(MoBook.class);
16????????System.out.println(b);
17????????if?(b)?{
18????????????//?3.2?Annotation?getAnnotation(Class?annotationClass)?獲取一個注解
19????????????MoBook?ann?=?method.getAnnotation(MoBook.class);
20????????????System.out.println(ann.name()?+?"::"?+?ann.price()?+?"::"?+?Arrays.toString(ann.authors()));
21????????}
22????}
23}
推薦閱讀:
推薦 33 個 IDEA 最牛配置,好用到飛起來! 阿里巴巴的獨立環(huán)境是如何實現(xiàn)的 2020 年 7 月編程語言排行榜 Java如何優(yōu)雅地實現(xiàn)單元測試與集成測試

