天天看點

學習Java注解

本文最後更新于 716 天前,其中的資訊可能已經有所發展或是發生改變。

轉自黑馬程式員

代碼位址

1.介紹

  • 概念:說明程式的。給計算機看的
  • 注釋:用文字描述程式的。給程式員看的
  • 定義:注解(Annotation),也叫中繼資料。一種代碼級别的說明。它是JDK1.5及以後版本引入的一個特性,與類、接口、枚舉是在同一個層次。它可以聲明在包、類、字段、方法、局部變量、方法參數等的前面,用來對這些元素進行說明,注釋。
  • 概念描述:
    • JDK1.5之後的新特性
    • 說明程式的
    • 使用注解:@注解名稱
  • 作用分類:
    1. 編寫文檔:通過代碼裡辨別的注解生成文檔【生成文檔doc文檔】
    2. 代碼分析:通過代碼裡辨別的注解對代碼進行分析【使用反射】
    3. 編譯檢查:通過代碼裡辨別的注解讓編譯器能夠實作基本的編譯檢查【

      Override

  • JDK中預定義的一些注解
    • @Override

      :檢測被該注解标注的方法是否是繼承自父類(接口)的
    • @Deprecated

      :該注解标注的内容,表示已過時
    • @SuppressWarnings

      :壓制警告
      • 一般傳遞參數all

        @SuppressWarnings("all")

2.使用

自定義注解

  • 格式:
元注解
public @interface 注解名稱{
    屬性清單;
}           

複制

  • 本質:注解本質上就是一個接口,該接口預設繼承Annotation接口(可通過反編譯

    javap

    得到)
    • public interface MyAnno extends java.lang.annotation.Annotation {}

  • 屬性:接口中的抽象方法
    • 要求:
      1. 屬性的傳回值類型有下列取值
        • 基本資料類型
        • String
        • 枚舉
        • 注解
        • 以上類型的數組
      2. 定義了屬性,在使用時需要給屬性指派
        1. 如果定義屬性時,使用default關鍵字給屬性預設初始化值,則使用注解時,可以不進行屬性的指派。
        2. 如果隻有一個屬性需要指派,并且屬性的名稱是value,則value可以省略,直接定義值即可。
        3. 數組指派時,值使用{}包裹。如果數組中隻有一個值,則{}可以省略
  • 元注解:用于描述注解的注解
    • @Target:描述注解能夠作用的位置
      • ElementType取值:
        • TYPE:可以作用于類上
        • METHOD:可以作用于方法上
        • FIELD:可以作用于成員變量上
    • @Retention:描述注解被保留的階段
      • @Retention(RetentionPolicy.RUNTIME):目前被描述的注解,會保留到class位元組碼檔案中,并被JVM讀取到
    • @Documented:描述注解是否被抽取到api文檔中
    • @Inherited:描述注解是否被子類繼承

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)){           

複制