Java注解(annotation)簡單上手
反射reflect:http://www.jfrwli.cn/article/211488.html
1、什么是注解?
注解就像商場的商品上都貼有自己的標(biāo)簽一樣,它提供了關(guān)于這個商品的許多額外信息。你可以根據(jù)這些信息對其進(jìn)行附加的處理。
“打上標(biāo)簽” 以后,框架就可以利用Java的反射能力,掃描、獲取各Class/Method/Field上的注解,據(jù)此對其進(jìn)行額外的處理。
2、java內(nèi)置注解
java中有一些java原生就定義的注解,像@Override
注解可以輔助反射機(jī)制,例如幫助我們快速篩選在反射中操作的目標(biāo),它在如今流行的框架中被大量使用
java內(nèi)置了一些注解,有些是輔助編譯器一起編譯時做驗證使用,下面兩個注解就是java內(nèi)置的注解,他們用于為我們定義的注解指定某些特性:
1
2
3
4
5
6
7
8
9
10
11
|
@Target 用于指定我們定義的注解可以被應(yīng)用在哪里,具體的位置被枚舉類型ElementType定義,例如: TYPE:在類上可以使用當(dāng)前注解,即只能標(biāo)注在類上 METHOD:在方法上可以使用當(dāng)前注解,即只能標(biāo)注在方法上 FIELD:在屬性上可以使用當(dāng)前注解,即只能標(biāo)注在屬性上 還有一些其他,可參見API手冊 @Retention 用于我們定義的注解的保留級別 RetentionPolice.RUNTIME:最常用,保留在字節(jié)碼文件中且在該類運行時可被反射機(jī)制利用 RetentionPolice.CLASS:保留在字節(jié)碼中,但是反射機(jī)制不可用,如若不寫默認(rèn)@Retention就是該級別 RetentionPolice.SOURCE:保留在源碼中 |
3、注解的基本運
創(chuàng)建注解
創(chuàng)建兩個注解類AutoRunClass和TestMethod
1
2
3
4
5
6
7
8
9
10
11
|
/* @Target()可以指定在哪使用這個注解 這個表示是給類(Type)使用的注解,表示只能在類上使用,不能在其他地方使用 @Target({ElementType.TYPE,ElementType.FIELD})也可以使用數(shù)組的方式使用多個 */ @Target (ElementType.TYPE) //保留級別 @Retention (RetentionPolicy.RUNTIME) public @interface AutoRunClass { //這個注解的作用于篩選類 } |
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@Target (ElementType.METHOD) @Retention (RetentionPolicy.RUNTIME) public @interface TestMethod { //這個注解的作用于篩選方法 /* 注解里可以定義參數(shù),格式: 類型 參數(shù)名() 注意:如果當(dāng)前注解只有一個參數(shù)時,通常參數(shù)名叫value 當(dāng)我們定義了參數(shù),那么在使用當(dāng)前注釋時需要為參數(shù)指定值,格式: @注解名(參數(shù)1=參數(shù)值1,參數(shù)1=參數(shù)值1,...) 參數(shù)指定的順序可以與注解中定義的順序不一樣 例如: @TestMethod(5) 注:上述注解沒有指定參數(shù)名的原因是該注解只有一個參數(shù),并且參數(shù)名叫value 即:int value(); 如果該參數(shù)定義時為:int sum(); 那么使用注解時要寫成:@TestMethod(sum=5) 注:使用default可以初始化定義值 */ int value() default 1 ; } |
創(chuàng)建一個實體類Person,在其中使用注解標(biāo)識類和方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
|
package reflect_text; /** * 用于測試反射-注解機(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 + "再見!" ); } 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í)行該方法。
如果對反射不是很了解,可以看看http://www.jfrwli.cn/article/221282.htm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
//加載Person的類對象 Class cls = Class.forName( "reflect_text.Person" ); /* boolean isAnnotationPresent(Class annoCls) 檢查是否又被annoCls指定的注解修飾 */ if (cls.isAnnotationPresent(AutoRunClass. class )) { System.out.println(cls.getName() + "被AutoRunClass注解修飾" ); //實例化 Object obj = cls.newInstance(); //掃描當(dāng)前類定義的所有方法 Method[] methods = cls.getDeclaredMethods(); for (Method method : methods) { if (method.isAnnotationPresent(TestMethod. class )) { System.out.println(method.getName()+ "被TestMethod注解修飾" ); //通過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() + "沒有被AutoRunClass注解修飾" ); } |
總結(jié)
本片文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注服務(wù)器之家的更多內(nèi)容!
原文鏈接:https://blog.csdn.net/Grantr/article/details/119973318