日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

java 注解妙用_框架开发之Java注解的妙用

發(fā)布時(shí)間:2025/3/15 java 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java 注解妙用_框架开发之Java注解的妙用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

PS:如果你還不會使用注解,你肯定不好意思對別人說你學(xué)過Spring,你學(xué)過Mybatis,因?yàn)樗鼈冇昧舜罅康淖⒔狻?梢娮⒔庠陂_發(fā)領(lǐng)域已經(jīng)使用的非常廣泛了。

配圖.jpg

注解的好處:

1.能夠讀懂別人寫的代碼,特別是框架相關(guān)的代碼。

2.本來可能需要很多配置文件,需要很多邏輯才能實(shí)現(xiàn)的內(nèi)容,就可以使用一個(gè)或者多個(gè)注解來替代,這樣就使得編程更加簡潔,代碼更加清晰。

3.(重點(diǎn))刮目相看。

(但是怎么樣才能讓別人刮目相看呢?會用注解不是目的,最重要的是要使用自定義注解來解決問題。)

舉個(gè)栗子:

如果面試的時(shí)候,你跟老板說你會使用注解,老板覺得你這個(gè)人還行;但是如果老板發(fā)現(xiàn)你會自定義注解解決問題,老板肯定就會眼前一亮。

注解這一概念是在java1.5版本提出的,說Java提供了一種原程序中的元素關(guān)聯(lián)任何信息和任何元數(shù)據(jù)的途徑的方法。

一、Java中的常見注解

1)JDK注解

JDK注解一共分為三類:

JDK注解.png

案例:

我們先新建一個(gè)接口people,如下:

public interface people {

public String name();

public int age();

public void work();

}

然后再建一個(gè)類Child實(shí)現(xiàn)類people這個(gè)接口,并實(shí)現(xiàn)該類的方法:

public class Child implements people {

@Override

public String name() {

return null;

}

@Override

public int age() {

return 0;

}

@Override

public void work() {

}

看到這里,我們發(fā)現(xiàn)這里的所有方法都會加上一個(gè)@Override標(biāo)記,它告訴我們,同時(shí)也告訴編譯器我們的這些方法肯定覆蓋了類people里面的方法的。假如說,我現(xiàn)在把類people里面的某一個(gè)方法注釋掉:

//public String name();

再看類Child里面的name方法就會報(bào)錯(cuò)。這樣,以后大家看到@Override的時(shí)候就能想到這個(gè)方法是覆蓋了某個(gè)接口的方法的。

然后,我們回過頭來看類people里面有一個(gè)work的方法。這里我們可以理解為人是要工作的,但是并不是所有的人都在工作,那么怎么辦呢?如果說這個(gè)接口正在用,我們不能刪除這個(gè)方法,這個(gè)時(shí)候我們就可以這樣:

@Deprecated

public void work();

@Deprecated標(biāo)記就表明這個(gè)方法已經(jīng)過時(shí)了,在實(shí)際中,它又有什么樣的應(yīng)用場景呢?我們在建一個(gè)測試類:

public class Test {

public void work() {

people people=new Child();

! people.work();

}

}

這個(gè)時(shí)候我們會發(fā)現(xiàn)myeclipse會給一個(gè)警告,并且在work中間出現(xiàn)一個(gè)破折號,意思就是這個(gè)方法已經(jīng)過時(shí)了。那么問題來了,雖然這個(gè)方法過時(shí)了,但是我們就是那么傲嬌,一定要用它,怎么辦呢?只需要這樣:

public class Test {

@SuppressWarnings("deprecation")

public void work() {

people people=new Child();

people.work();

}

}

這樣我們就忽略了這個(gè)警告。@SuppressWarnings("deprecation")就表示我們忽略了deprecation這樣的一個(gè)警告。

2)Java第三方注解

第三方注解.png

二、注解的分類

1)按照運(yùn)行機(jī)制劃分:

【源碼注解→編譯時(shí)注解→運(yùn)行時(shí)注解】

源碼注解:只在源碼中存在,編譯成.class文件就不存在了。

編譯時(shí)注解:在源碼和.class文件中都存在。像前面的@Override、@Deprecated、@SuppressWarnings,他們都屬于編譯時(shí)注解。

運(yùn)行時(shí)注解:在運(yùn)行階段還起作用,甚至?xí)绊戇\(yùn)行邏輯的注解。像@Autowired自動注入的這樣一種注解就屬于運(yùn)行時(shí)注解,它會在程序運(yùn)行的時(shí)候把你的成員變量自動的注入進(jìn)來。

2)按照來源劃分:

【來自JDK的注解——來自第三方的注解——自定義注解】

3)元注解:

元注解是給注解進(jìn)行注解,可以理解為注解的注解就是元注解。

三、自定義注解

我們分四步來解析自定義注解:

自定義注解的語法要求:

@Target({ElementType.METHOD,ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Inherited

@Documented

public @interface Description {

String desc();

String author();

int age() default 18;

}

首先我們要明確這不是一個(gè)接口,它是使用@interface關(guān)鍵字定義的一個(gè)注解。

然后我們看下面的幾個(gè)方法,String desc();雖然它很類似于接口里面的方法,其實(shí)它在注解里面只是一個(gè)成員變量(成員以無參無異常的方式聲明),int age() default 18;(成員變量可以用default指定一個(gè)默認(rèn)值的)。

最后我們要知道:

①.成員類型是受限制的,合法的類型包括基本的數(shù)據(jù)類型以及String,Class,Annotation,Enumeration等。

②.如果注解只有一個(gè)成員,則成員名必須取名為value(),在使用時(shí)可以忽略成員名和賦值號(=)。

③.注解類可以沒有成員,沒有成員的注解稱為標(biāo)識注解。

元注解:

有沒有發(fā)現(xiàn)上面那段代碼有一個(gè)沒有說呢?沒錯(cuò),它們就是我們所說的元注解:

@Target({ElementType.METHOD,ElementType.TYPE})

@Retention(RetentionPolicy.RUNTIME)

@Inherited

@Documented

我們先看第一行:@Target是這個(gè)注解的作用域,ElementType.METHOD是這個(gè)注解的作用域的列表,METHOD是方法聲明,除此之外,還有:

CONSTRUCTOR(構(gòu)造方法聲明),FIELD(字段聲明),LOCAL VARIABLE(局部變量聲明),METHOD(方法聲明),PACKAGE(包聲明),PARAMETER(參數(shù)聲明),TYPE(類接口)

第二行:@Retention是它的生命周期,前面不是說注解按照運(yùn)行機(jī)制有一個(gè)分類嘛,RUNTIME就是在運(yùn)行時(shí)存在,可以通過反射讀取。除此之外,還有:

SOURCE(只在源碼顯示,編譯時(shí)丟棄),CLASS(編譯時(shí)記錄到class中,運(yùn)行時(shí)忽略),RUNTIME(運(yùn)行時(shí)存在,可以通過反射讀取)

第三行:@Inherited是一個(gè)標(biāo)識性的元注解,它允許子注解繼承它。

第四行:@Documented,生成javadoc時(shí)會包含注解。

使用自定義注解:

使用注解的語法:

@(=,=,...)

案例:

@Description(desc="i am Color",author="boy",age=18)

public String Color() {

return "red";

}

這里的Description是我們剛才在自定義注解語法要求里面定義的注解噢,然后我們可以給它的每一個(gè)成員變量賦值,注意數(shù)據(jù)類型。值得注意的是,因?yàn)槲覀兦懊娑x的作用域是在方法和類接口上,所以這個(gè)注解在Color()方法上使用是沒問題的。

解析注解

概念:

通過反射獲取類 、函數(shù)或成員上的運(yùn)行時(shí)注解信息,從而實(shí)現(xiàn)動態(tài)控制程序運(yùn)行的邏輯。

準(zhǔn)備工作:

Description類.png

Child類.png

接下來,我們就開始測試了:

public class ParseAnn {

public static void main(String[] args) {

try {

// 使用類加載器加載類

Class c = Class.forName("com.test.Child");

// 找到類上面的注解

boolean isExist = c.isAnnotationPresent(Description.class);

// 上面的這個(gè)方法是用這個(gè)類來判斷這個(gè)類是否存在Description這樣的一個(gè)注解

if (isExist) {

// 拿到注解實(shí)例,解析類上面的注解

Description d = (Description) c.getAnnotation(Description.class);

System.out.println(d.value());

}

} catch (ClassNotFoundException e) {

e.printStackTrace();

}

}

}

輸出的結(jié)果:

i am class annotation

可以看到,我們成功的解析了Child類上面的注解。

接下來,我們繼續(xù)解析方法上的注解:

//獲取所有的方法

Method[] ms = c.getMethods();

// 遍歷所有的方法

for (Method m : ms) {

boolean isExist1 = m.isAnnotationPresent(Description.class);

if (isExist1) {

Description d1=m.getAnnotation(Description.class);

System.out.println(d1.value());

}

}

輸出的結(jié)果:

i am class annotation

i am method annotation

可以看到,我們成功的解析了方法上面的注解。

//另一種解析方法

for (Method m : ms) {

//拿到方法上的所有的注解

Annotation[] as=m.getAnnotations();

for (Annotation a : as) {

//用二元操作符判斷a是否是Description的實(shí)例

if (a instanceof Description) {

Description d=(Description) a;

System.out.println(d.value());

}

}

}

也可以得到上面的效果。

此時(shí),如果把Description類里面的元注解改一下,比如:

@Retention(RetentionPolicy.RUNTIME)→@Retention(RetentionPolicy.SOURCE),再運(yùn)行程序,結(jié)果會成怎樣呢?如果改成CLASS呢?讀者們要不要試一試?

如果看過我寫的《談?wù)凧AVA反射機(jī)制》——Class類的動態(tài)加載的讀者,仔細(xì)想一下我們這個(gè)環(huán)境,就知道為什么了。

如果大家覺得我寫的對你有幫助,請順手點(diǎn)個(gè)贊支持一下唄;如果大家覺得我有寫的不對的地方,歡迎大家多多發(fā)言。謝謝!

轉(zhuǎn)載請注明作者及文章出處噢!

總結(jié)

以上是生活随笔為你收集整理的java 注解妙用_框架开发之Java注解的妙用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。