做一個自定義注解


一、注解是什么
  1. 注解的定義
    • 注解是一種元數據形式(元數據就是冠以數據的數據), 即注解是屬於java的一種數據類型,和類、接口、數組、枚舉類似。
    • 注解用來修飾,類、方法、變量、參數、包 。
    • 注解不會對所修飾的代碼產生直接的影響。
        2. 注解可以干嘛,注解的基本作用
    • 生成文檔
    • 代替配置文件的功能
    • 編譯時進行格式檢查
 
二、使用注解的好處
  • 注解與xml配置的區別
    • 注解:是一種分散式的元數據,與源代碼耦合。
    • xml :是一種集中式的元數據,與源代碼解耦。
  • 注解的缺點
    • 因為會分散到很多類中所以不好管理和維護
    • 如果需要更改會改變源代碼
    • 缺乏靈活性
    • 缺乏可擴展性和復雜性
  • 注解的優點
    • 注解比較方便
    • 簡化配置提高開發效率
    • 類型安全,xml只有在運行時才能發現問題
 
三、注解是干嘛的
  • 標准注解
    • @Override
    • @Deprecated
    • @SuppressWarnings
  • 元注解
    • @Retention(注解保留策略)
      • @Retention(RetentionPolicy.SOURCE)   // 注解僅存在於源碼中,在class字節碼文件中不包含
      • @Retention(RetentionPolicy.CLASS)     // 默認的保留策略,注解會在class字節碼文件中存在,但運行時無法獲得
      • @Retention(RetentionPolicy.RUNTIME)  // 注解會在class字節碼文件中存在,在運行時可以通過反射獲取到
    • @Target(注解的作用目標)
      • @Target(ElementType.TYPE)                      // 接口、類、枚舉、注解
      • @Target(ElementType.FIELD)                     // 字段、枚舉的常量
      • @Target(ElementType.METHOD)                 // 方法
      • @Target(ElementType.PARAMETER)            // 方法參數
      • @Target(ElementType.CONSTRUCTOR)       // 構造函數
      • @Target(ElementType.LOCAL_VARIABLE)   // 局部變量
      • @Target(ElementType.ANNOTATION_TYPE) // 注解
      • @Target(ElementType.PACKAGE)               // 包
    • @Documented(注解包含在javadoc中)
    • @Inhertied(允許子類繼承父類中的注解)
 
四、如何使用自定義注解
  •  定義注解
    • 定義注解用@interface 來標識 會自動繼承java.lang.annotation.Annotation接口
    • 注解類型元素
      • 基本類型
      • String
      • class
      • enum
      • annotation
      • 以上類型的數組
  • 配置注解
package com.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* 自定義日志注解 
* Retention(RetentionPolicy.RUNTIME) 生命周期永遠不會被丟棄
* Target(ElementType.METHOD) 作用於方法上
* @author 果咩
*/

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface LogAnnotation {

   // 描述
   String actiondese() default "";

   //類型
   public enum Logtype {ADD,UPDATE,DEL,SET,LOGIN,LOGOUT,MESSAGE};
   Logtype actionvalue() default Logtype.ADD;

}
  • 解析注解
    • <T extends Annotation> T getAnnotation(Class<T> annotationClass): 返回改程序元素上存在的、指定類型的注解,如果該類型注解不存在,則返回null。
    • Annotation[] getAnnotations():返回該程序元素上存在的所有注解。
    • boolean is AnnotationPresent(Class<?extends Annotation> annotationClass):判斷該程序元素上是否包含指定類型的注解,存在則返回true,否則返回false.
    • Annotation[] getDeclaredAnnotations():返回直接存在於此元素上的所有注釋。與此接口中的其他方法不同,該方法將忽略繼承的注釋。(如果沒有注釋直接存在於此元素上,則返回長度為零的一個數組。)該方法的調用者可以隨意修改返回的數組;這不會對其他調用者返回的數組產生任何影響。
public class TestAnnotation {
    public static void main(String[] args){
        try {
            //獲取Student的Class對象
            Class stuClass = Class.forName("pojos.Student");

            //說明一下,這里形參不能寫成Integer.class,應寫為int.class
                        //獲取注解所標注的方法
            Method stuMethod = stuClass.getMethod("study",int.class);

            if(stuMethod.isAnnotationPresent(LogAnnotation.class)){
                System.out.println("Student類上配置了logAnnotation注解!");
                //獲取該元素上指定類型的注解
                LogAnnotation logAnnotation= stuMethod.getAnnotation(LogAnnotation.class);
                                //打印
                System.out.println("actionDesc: " +logAnnotation.actiondese() + ",actionvalue: " + logAnnotation.actionvalue());
            }else{
                System.out.println("Student類上沒有配置logAnnotation注解!");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM