JDK中的三個基本注解
a、@Override:檢查子類確實是覆蓋了父類的方法。
b、@Deprecated:說明已經過時了。
c、@SuppressWarnings({ "unused", "deprecation" }):抑制程序中的警告。unused警告的類型。{}數組。all抑制所有警告。
簡單使用:
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 注解名{}
public @interface MyAnnotation{}
注解它的本質就是一個接口,這個接口需要繼承 Annotation接口。
public interface MyAnnotation extends java.lang.annotation.Annotation {}
注解的屬性類型:
具體是怎樣定義的呢,我們看代碼:
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}
使用自定義注解:
public class Demo2 { //@MyAnno1(age=25,name={"jack","lucy"},value="zhengzhi") //@MyAnno1(value="zhengzhi") @MyAnno1(value="zhengzhi",love=Love.eat) public void tests() { }}
如果在沒有默認值的情況下,使用自定義注解我們需要設置注解中屬性的值。
注解的反射:(靈魂)
模擬Junit的@Testa、反射注解類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
import java.lang.annotation.Retention;import java.lang.annotation.RetentionPolicy;//元注解: 用來注解注解的@Retention(RetentionPolicy.RUNTIME)public @interface MyTest { long timeout() default Integer.MAX_VALUE;//設置超時時間的}
這是我們使用注解的類:
public class DBCRUD { @MyTest(timeout=1000000) public void addTest() { System.out.println("addTest方法執行了"); } @MyTest public void updateTest() { System.out.println("updateTest方法執行了"); }}
當我們使用了注解,我們就需要判該類是否使用了注解,我們通過反射來實現。
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方法沒有考慮到超時的問題,下面我們再完善一下。
//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("運行超時"); } } }
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對VeVb武林網的支持。
新聞熱點
疑難解答
圖片精選