Java注解(annotation)簡(jiǎn)述
Java注解(annotation)簡(jiǎn)單上手
反射reflect:http://www.dbjr.com.cn/article/221282.htm
1、什么是注解?
注解就像商場(chǎng)的商品上都貼有自己的標(biāo)簽一樣,它提供了關(guān)于這個(gè)商品的許多額外信息。你可以根據(jù)這些信息對(duì)其進(jìn)行附加的處理。
“打上標(biāo)簽” 以后,框架就可以利用Java的反射能力,掃描、獲取各Class/Method/Field上的注解,據(jù)此對(duì)其進(jìn)行額外的處理。
2、java內(nèi)置注解
java中有一些java原生就定義的注解,像@Override
注解可以輔助反射機(jī)制,例如幫助我們快速篩選在反射中操作的目標(biāo),它在如今流行的框架中被大量使用
java內(nèi)置了一些注解,有些是輔助編譯器一起編譯時(shí)做驗(yàn)證使用,下面兩個(gè)注解就是java內(nèi)置的注解,他們用于為我們定義的注解指定某些特性:
@Target
用于指定我們定義的注解可以被應(yīng)用在哪里,具體的位置被枚舉類(lèi)型ElementType定義,例如:
TYPE:在類(lèi)上可以使用當(dāng)前注解,即只能標(biāo)注在類(lèi)上
METHOD:在方法上可以使用當(dāng)前注解,即只能標(biāo)注在方法上
FIELD:在屬性上可以使用當(dāng)前注解,即只能標(biāo)注在屬性上
還有一些其他,可參見(jiàn)API手冊(cè)
@Retention
用于我們定義的注解的保留級(jí)別
RetentionPolice.RUNTIME:最常用,保留在字節(jié)碼文件中且在該類(lèi)運(yùn)行時(shí)可被反射機(jī)制利用
RetentionPolice.CLASS:保留在字節(jié)碼中,但是反射機(jī)制不可用,如若不寫(xiě)默認(rèn)@Retention就是該級(jí)別
RetentionPolice.SOURCE:保留在源碼中
3、注解的基本運(yùn)
創(chuàng)建注解

創(chuàng)建兩個(gè)注解類(lèi)AutoRunClass和TestMethod
/*
@Target()可以指定在哪使用這個(gè)注解
這個(gè)表示是給類(lèi)(Type)使用的注解,表示只能在類(lèi)上使用,不能在其他地方使用
@Target({ElementType.TYPE,ElementType.FIELD})也可以使用數(shù)組的方式使用多個(gè)
*/
@Target(ElementType.TYPE)
//保留級(jí)別
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoRunClass {//這個(gè)注解的作用于篩選類(lèi)
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestMethod {//這個(gè)注解的作用于篩選方法
/*
注解里可以定義參數(shù),格式:
類(lèi)型 參數(shù)名()
注意:如果當(dāng)前注解只有一個(gè)參數(shù)時(shí),通常參數(shù)名叫value
當(dāng)我們定義了參數(shù),那么在使用當(dāng)前注釋時(shí)需要為參數(shù)指定值,格式:
@注解名(參數(shù)1=參數(shù)值1,參數(shù)1=參數(shù)值1,...)
參數(shù)指定的順序可以與注解中定義的順序不一樣
例如:
@TestMethod(5)
注:上述注解沒(méi)有指定參數(shù)名的原因是該注解只有一個(gè)參數(shù),并且參數(shù)名叫value
即:int value();
如果該參數(shù)定義時(shí)為:int sum();
那么使用注解時(shí)要寫(xiě)成:@TestMethod(sum=5)
注:使用default可以初始化定義值
*/
int value() default 1;
}
創(chuàng)建一個(gè)實(shí)體類(lèi)Person,在其中使用注解標(biāo)識(shí)類(lèi)和方法
package reflect_text;
/**
* 用于測(cè)試反射-注解機(jī)制
*/
@AutoRunClass//-----------------------
public class Person {
private String name = "劉瑜澄";
private int age = 22;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
//有了初始值,加不加參數(shù)都可以
@TestMethod//-----------------------
public void sayHi() {
System.out.println(name + "Hi!!!");
}
@TestMethod(3)//-----------------------
public void sayHello() {
System.out.println(name + "大家好!");
}
@TestMethod(5)//-----------------------
public void sayGoodBye() {
System.out.println(name + "再見(jiàn)!");
}
public void say(String info) {
System.out.println(name + ":" + info);
}
public void say(String info, int sum) {
for (int i = 0; i < sum; i++) {
System.out.println(name + ":" + info);
}
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
使用注解
要求判斷Person是否被AutoRunClass注解修飾,如果是則遍歷Person中所有方法,遍歷判斷這些方法是否被TestMethod注解修飾,是則根據(jù)注解傳入的參數(shù)去遍歷執(zhí)行該方法。
如果對(duì)反射不是很了解,可以看看http://www.dbjr.com.cn/article/221282.htm
//加載Person的類(lèi)對(duì)象
Class cls = Class.forName("reflect_text.Person");
/*
boolean isAnnotationPresent(Class annoCls)
檢查是否又被annoCls指定的注解修飾
*/
if (cls.isAnnotationPresent(AutoRunClass.class)) {
System.out.println(cls.getName() + "被AutoRunClass注解修飾");
//實(shí)例化
Object obj = cls.newInstance();
//掃描當(dāng)前類(lèi)定義的所有方法
Method[] methods = cls.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(TestMethod.class)) {
System.out.println(method.getName()+"被TestMethod注解修飾");
//通過(guò)getAnnotation方法獲取method方法上的注解@TestMethod
TestMethod tm = method.getAnnotation(TestMethod.class);
//調(diào)用其參數(shù)名,獲取注解 參數(shù)value的值
int sum = tm.value();
//然后根據(jù)注解傳入的參數(shù)重復(fù)調(diào)用該方法
for (int i = 0; i < sum; i++) {
method.invoke(obj);
}
}else{
System.out.println(method.getName() + "不被@TestMethod注解修飾");
}
}
} else {
System.out.println(cls.getName() + "沒(méi)有被AutoRunClass注解修飾");
}

總結(jié)
本片文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
SpringBoot集成canal實(shí)現(xiàn)示例解析
這篇文章主要為大家介紹了springboot整合canal的示例實(shí)現(xiàn)解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多多進(jìn)步,早日升職加薪2022-02-02
mybatis解決<foreach>標(biāo)簽不能超過(guò)1000的問(wèn)題
MyBatis是一個(gè)開(kāi)源的持久層框架,它可以幫助開(kāi)發(fā)者簡(jiǎn)化數(shù)據(jù)庫(kù)操作的編寫(xiě),而foreach是MyBatis中的一個(gè)重要標(biāo)簽,用于在SQL語(yǔ)句中進(jìn)行循環(huán)操作,本文主要給大家介紹了mybatis解決<foreach>標(biāo)簽不能超過(guò)1000的問(wèn)題,需要的朋友可以參考下2024-05-05
IntelliJ IDEA 安裝及初次使用圖文教程(2020.3.2社區(qū)版)
這篇文章主要介紹了IntelliJ IDEA 安裝及初次使用(2020.3.2社區(qū)版),本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03
通過(guò)netty把百度地圖API獲取的地理位置從Android端發(fā)送到Java服務(wù)器端的操作方法
這篇文章主要介紹了通過(guò)netty把百度地圖API獲取的地理位置從Android端發(fā)送到Java服務(wù)器端,本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-10-10

