本文最後更新于 716 天前,其中的資訊可能已經有所發展或是發生改變。
轉自黑馬程式員
代碼位址
1.介紹
- 概念:說明程式的。給計算機看的
- 注釋:用文字描述程式的。給程式員看的
- 定義:注解(Annotation),也叫中繼資料。一種代碼級别的說明。它是JDK1.5及以後版本引入的一個特性,與類、接口、枚舉是在同一個層次。它可以聲明在包、類、字段、方法、局部變量、方法參數等的前面,用來對這些元素進行說明,注釋。
- 概念描述:
- JDK1.5之後的新特性
- 說明程式的
- 使用注解:@注解名稱
- 作用分類:
- 編寫文檔:通過代碼裡辨別的注解生成文檔【生成文檔doc文檔】
- 代碼分析:通過代碼裡辨別的注解對代碼進行分析【使用反射】
- 編譯檢查:通過代碼裡辨別的注解讓編譯器能夠實作基本的編譯檢查【
】Override
- JDK中預定義的一些注解
-
:檢測被該注解标注的方法是否是繼承自父類(接口)的@Override
-
:該注解标注的内容,表示已過時@Deprecated
-
:壓制警告@SuppressWarnings
- 一般傳遞參數all
@SuppressWarnings("all")
- 一般傳遞參數all
-
2.使用
自定義注解
- 格式:
元注解
public @interface 注解名稱{
屬性清單;
}
複制
- 本質:注解本質上就是一個接口,該接口預設繼承Annotation接口(可通過反編譯
得到)javap
-
public interface MyAnno extends java.lang.annotation.Annotation {}
-
- 屬性:接口中的抽象方法
- 要求:
- 屬性的傳回值類型有下列取值
- 基本資料類型
- String
- 枚舉
- 注解
- 以上類型的數組
- 定義了屬性,在使用時需要給屬性指派
- 如果定義屬性時,使用default關鍵字給屬性預設初始化值,則使用注解時,可以不進行屬性的指派。
- 如果隻有一個屬性需要指派,并且屬性的名稱是value,則value可以省略,直接定義值即可。
- 數組指派時,值使用{}包裹。如果數組中隻有一個值,則{}可以省略
- 屬性的傳回值類型有下列取值
- 要求:
- 元注解:用于描述注解的注解
- @Target:描述注解能夠作用的位置
- ElementType取值:
- TYPE:可以作用于類上
- METHOD:可以作用于方法上
- FIELD:可以作用于成員變量上
- ElementType取值:
- @Retention:描述注解被保留的階段
- @Retention(RetentionPolicy.RUNTIME):目前被描述的注解,會保留到class位元組碼檔案中,并被JVM讀取到
- @Documented:描述注解是否被抽取到api文檔中
- @Inherited:描述注解是否被子類繼承
- @Target:描述注解能夠作用的位置
3.實戰
在程式使用(解析)注解:擷取注解中定義的屬性值
擷取注解定義的位置的對象 (Class,Method,Field)
擷取指定的注解
-
getAnnotation(Class)
//其實就是在記憶體中生成了一個該注解接口的子類實作對象
public class ProImpl implements Pro{
public String className(){
return "cn.itcast.annotation.Demo1";
}
public String methodName(){
return "show";
}
}
複制
調用注解中的抽象方法擷取配置的屬性值
@org.junit.jupiter.api.Test
public void testReflect() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
Class<Test> testClass = Test.class;
MyAnno3 myAnno3 = testClass.getAnnotation(MyAnno3.class);
Class<?> clazz = Class.forName(myAnno3.className());
Method method = clazz.getMethod(myAnno3.methodName(),int.class,int.class);
method.invoke(clazz.newInstance(), 2,4);
}
複制
判斷方法上是否有Check注解
for (Method method : methods) {
//4.判斷方法上是否有Check注解
if(method.isAnnotationPresent(Check.class)){
複制