jdk中的三個基本注解
a、@override:檢查子類確實是覆蓋了父類的方法。
b、@deprecated:說明已經過時了。
c、@suppresswarnings({ "unused", "deprecation" }):抑制程序中的警告。unused警告的類型。{}數組。all抑制所有警告。
簡單使用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
|
public class demo1 { //@suppresswarnings({ "deprecation", "unused" }) @suppresswarnings ( "all" ) public void fun() { int i = 5 ; system.out.println( "hello" ); system.out.println( new date().tolocalestring()); } } class tests extends demo1 { @override public void fun() { super .fun(); } @deprecated public void tt() { system.out.println( new date().tolocalestring()); } } |
聲明一個注解 @interface 注解名{}
1
|
public @interface myannotation{} |
注解它的本質就是一個接口,這個接口需要繼承 annotation接口。
1
2
|
public interface myannotation extends java.lang.annotation.annotation { } |
注解的屬性類型:
- 1.基本類型
- 2.string
- 3.枚舉類型
- 4.注解類型
- 5.class類型
- 6.以上類型的一維數組類型
具體是怎樣定義的呢,我們看代碼:
1
2
3
4
5
6
7
8
9
10
|
public @interface myanno1 { //注解中定義的都是屬性 int age() default 20 ; string[] name() default "hehe" ; string value() default "haha" ; love love(); //myanno2 anno(); //public static final int num = 5;//可以 //public abstract void fun();//error } |
使用自定義注解:
1
2
3
4
5
6
7
8
|
public class demo2 { //@myanno1(age=25,name={"jack","lucy"},value="zhengzhi") //@myanno1(value="zhengzhi") @myanno1 (value= "zhengzhi" ,love=love.eat) public void tests() { } } |
如果在沒有默認值的情況下,使用自定義注解我們需要設置注解中屬性的值。
注解的反射:(靈魂)
1
2
3
4
5
6
7
8
9
10
|
模擬junit的 @test a、反射注解類 java.lang.reflect.annotatedelement: ?<t extends annotation> t getannotation( class <t> annotationtype):得到指定類型的注解引用。沒有返回 null 。 ?annotation[] getannotations():得到所有的注解,包含從父類繼承下來的。 ?annotation[] getdeclaredannotations():得到自己身上的注解。 boolean isannotationpresent( class <? extends annotation> annotationtype):判斷指定的注解有沒有。 class 、method、field、constructor等實現了annotatedelement接口. 如果: class .isannotationpresent(mytest. class ):判斷類上面有沒有 @mytest 注解; method.isannotationpresent(mytest. class ):判斷方法上面有沒有 @mytest 注解。 |
下面通過代碼實現一下。
我們模擬實現@test注解的功能
首先這是我們的注解@mytest
1
2
3
4
5
6
7
|
import java.lang.annotation.retention; import java.lang.annotation.retentionpolicy; //元注解: 用來注解注解的 @retention (retentionpolicy.runtime) public @interface mytest { long timeout() default integer.max_value; //設置超時時間的 } |
這是我們使用注解的類:
1
2
3
4
5
6
7
8
9
10
11
12
|
public class dbcrud { @mytest (timeout= 1000000 ) public void addtest() { system.out.println( "addtest方法執行了" ); } @mytest public void updatetest() { system.out.println( "updatetest方法執行了" ); } } |
當我們使用了注解,我們就需要判該類是否使用了注解,我們通過反射來實現。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
private static void method1() throws illegalaccessexception, invocationtargetexception, instantiationexception { class claz = dbcrud. class ; //得到字節碼文件對象 //得到該類及父類中的所有方法 method[] methods = claz.getmethods(); for (method m:methods){ //判斷方法是否使用了@mytest這個注解 // boolean boo = m.isannotationpresent(mytest.class); // system.out.println(m.getname()+"===="+boo);//都是false 默認注解存活到 class,改變存活到runtime if (m.isannotationpresent(mytest. class )){ m.invoke(claz.newinstance(), null ); } } } |
這里我們需要注意的是,我們需要考慮到自定義注解的存活范圍。
默認的自定義注解只存活到編譯時期,class階段。
可以注意到,我們上面的自定義注解應用了@retention注解,這個注解就是改變自定義注解的存活范圍。
這個注解也叫做元注解,只能用在注解上的注解叫做元注解。
上面的method方法沒有考慮到超時的問題,下面我們再完善一下。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
//method1(); //反射解析注解的屬性 class claz = dbcrud. class ; method[] methods = claz.getmethods(); for (method m:methods){ //從該方法上獲取mytest注解 mytest mt = m.getannotation(mytest. class ); if (mt!= null ){ //得到注解中的屬性 long out = mt.timeout(); long start = system.nanotime(); m.invoke(claz.newinstance(), null ); long end = system.nanotime(); if ((end-start)>out) { system.out.println( "運行超時" ); } } } |
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對服務器之家的支持。如果你想了解更多相關內容請查看下面相關鏈接
原文鏈接:https://blog.csdn.net/melissa_heixiu/article/details/52768816