自定義註解以及註解在反射中的應用

abstractcyj發表於2022-02-28

✿ 註解三要素:註解本身、被貼者、第三方程式(賦予註解的特殊功能)

 

目錄

 

一、Annotation註解(也加標註)

■  作用在程式碼的註解和元註解:

□   作用在程式碼的註解:

□    元註解(作用在其他註解的註解):

□   重點介紹一下@Retention 和 @Target:

 

❀ 註解重要應用:在反射中使用 Annotation

(1)註解在類名上:

(2)註解在方法名上:

(3)註解在屬性上:

總結:自定義註解的使用

❀ 註解本質就是抽象類【把它理解成類自定義跟使用起來就so easy】

1、定義一個註解類:

2、使用註解(‘貼一下’)【因為定義的註解的註解範圍是類,只能貼在類上】

3、獲取自定義註解標籤中值,即呼叫自定義註解類中的方法


 

一、Annotation註解(也加標註)

      Java 中的類、方法、變數、引數和包等都可以被標註。和 Javadoc 不同Java 標註可以通過反射獲取標註內容(反射獲取註解內容:編譯器生成類檔案時,標註可以被嵌入到位元組碼中。Java 虛擬機器可以保留標註內容,在執行時可以獲取到標註內容。)

■    註解包括:內建的註解 和 自定義註解

其中內建的註解:Java 定義了一套註解,共有 7 個,3 個在 java.lang 中,剩下 4 個在 java.lang.annotation 中。

 

■  作用在程式碼的註解和元註解:

□   作用在程式碼的註解:

  • @Override - 檢查該方法是否是重寫方法。如果發現其父類,或者是引用的介面中並沒有該方法時,會報編譯錯誤。
  • @Deprecated - 標記過時方法。如果使用該方法,會報編譯警告。
  • @SuppressWarnings - 指示編譯器去忽略註解中宣告的警告。

□    元註解(作用在其他註解的註解):

  • @Retention - 標識這個註解怎麼儲存,是隻在程式碼中,還是編入class檔案中,或者是在執行時可以通過反射訪問。
  • @Documented - 標記這些註解是否包含在使用者文件中。
  • @Target - 標記這個註解應該是哪種 Java 成員。
  • @Inherited - 標記這個註解是繼承於哪個註解類(預設 註解並沒有繼承於任何子類)

 

□   重點介紹一下@Retention 和 @Target:

@Retention:註解的保留範圍,是個列舉,有如下可選值
    RetentionPolicy.SOURCE:註解存在於原始檔中
    RetentionPolicy.CLASS:註解存在於源位元組碼檔案中
    RetentionPolicy.RUNTIME:註解存在於執行時

@Target:註解出現的位置(比如類上、欄位上、方法上等等),也是個列舉,有如下可選值
  ElementType.ANNOTATION _ type 應用於註釋型別。
  ElementType.CONSTRUCTOR 應用於建構函式。
  ElementType.FIELD 應用於欄位或屬性。
  ElementType.LOCAL_VARIABLE 應用於區域性變數。
  ElementType.METHOD應用於方法級註釋。
  ElementType.PACKAGE 應用於包宣告。
  ElementType.PARAMETER 應用於方法的引數。
  ElementType.TYPE應用於類的任何元素。

 

❀ 註解重要應用:在反射中使用 Annotation

(1)註解在類名上:

1):@註解名(“註解值”) :註解在類名上,則該類擁有了註解中資訊  
     @Table(“t_student”)
     public class Student{
        ……
     }

 2): 然後建立註解:
●貼哪裡:   @Target(ElementType.Type)
●儲存時間: @Retention(RetentionPolicy.RUNTIME)
           public @interface Table {
                 String value();   //則使用@Table註解的時候: @Table(value=”t_student”);
            }    

 3): (該類擁有了註解中資訊)使用反射獲取註解資訊:
     //建立註解物件:獲取到Student類上的註解物件
  ① 建立註解物件       Table table = Student類.getAnnotation(Table.class);
  ② 呼叫註解物件的方法  String tableName =table.value();

(2)註解在方法名上:

    1)student類中的方法test上有註解:    
    @MyAnnotation(value = "123",name = "lisi")
    public static void test(){
        ……
     }

    2)然後建立註解:
    ●貼哪裡:  @Target(ElementType.Type)
    ●儲存時間:@Retention(RetentionPolicy.RUNTIME)
              public @interface MyAnnotation {
                    String value() default "abc";
                    String name() default "zhangsan";
              }

    3)(該類的方法擁有了註解中資訊)使用反射獲取註解資訊:
         Class clazz = Class.forName("Student的路徑");
         Method[] ms = clazz.getMethods();
         for (Method m : ms) {
            if(m.isAnnotationPresent(MyAnnotation.class)){
              //建立註解物件:獲取到test方法上的註解物件;並呼叫註解物件的方法
                String value = m.getAnnotation(MyAnnotation.class).value();
           String name = m.getAnnotation(MyAnnotation.class).name();
            }
        }

(3)註解在屬性上:

 1)student類中的屬性id上有註解:
    @Sid(min = 6,max = 10)
     private int id;
 2)然後建立註解:
    ●貼哪裡:  @Target(ElementType.Type)
    ●儲存時間:@Retention(RetentionPolicy.RUNTIME)
              public @interface Sid{
                 int min() default 1;
                 int max() default 10;
             }
 3)(該類的屬性擁有了註解中資訊)使用反射獲取註解資訊:
       Class clazz = Class.forName("Student的路徑");
       Field[] fs = clazz.getDeclaredFields();
       for (Field f: fs){
            //建立註解物件:獲取屬性上的@Sid註解
            Sid id = f.getAnnotation(Test.class); 
            if(id != null){
                f.setAccessible(true);//設定屬性可訪問 
              //呼叫註解物件的方法
                   int min = id.min();
                  int max = id.max();
                }
        }

總結:自定義註解的使用

❀ 註解本質就是抽象類【把它理解成類自定義跟使用起來就so easy】

1、定義一個註解類:

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME)
 public @interface Table{
 	String value();
 } 

● @Target(ElementType.TYPE) 是元註解,表示自定義的註解類Table 註解的範圍是TYPE 類。

●  @Retention(RetentionPolicy.RUNTIME) 也是元註解,表示自定義的註解類Table 註解生效是在執行RUNTIME 的時候。

 

2、使用註解(‘貼一下’)【因為定義的註解的註解範圍是類,只能貼在類上】

 @Table("t_stu") //本來應該寫成 @Table(value="t_stu"),因為自定義註解類只有一個方法,簡寫
 public class Student{
 
 }


//===============================================================================

//自定義註解中有多個方法,例如一下:
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME)
 public @interface Table{
 	String value();
    String name();
 } 


//貼標籤
 @Table(value="fupo" name="xiaoming")  
 public class Student{
     
 }

3、獲取自定義註解標籤中值,即呼叫自定義註解類中的方法

● 建立自定義註解物件,利用自定義註解物件呼叫方法

//獲取註解標籤中的值:

//(1) 先建立註解物件 
Table table = classType.getAnnotation(Table.class);
//【因為註解在類上】 類.getAnnotation(註解標籤類))
//【若是註解在屬性】就使用: 屬性.getAnnotation(註解類) 

//(2)呼叫註解標籤類中定義的方法, 獲取註解標籤中傳遞的值 
String tableName = table.value();

 

相關文章