Java實現自定義注解開發


Java實現自定義注解開發

 

一直都對注解開發挺好奇的,最近終於有時間自己實踐了一把,記錄一下 萬一后期會用到呢 哈哈哈 

首先我們了解一下自定義注解的標准示例,注解類使用 @interface 關鍵字修飾,且在注解類上方聲明注解相關信息,包含以下四種信息

@Documented – 注解是否將包含在JavaDoc中

@Retention – 什么時候使用該注解

@Target – 注解用於什么地方

@Inherited – 是否允許子類繼承該注解

  

 1.)@Retention – 定義該注解的生命周期

●   RetentionPolicy.SOURCE : 在編譯階段丟棄。這些注解在編譯結束之后就不再有任何意義,所以它們不會寫入字節碼。@Override, @SuppressWarnings都屬於這類注解。
●   RetentionPolicy.CLASS : 在類加載的時候丟棄。在字節碼文件的處理中有用。注解默認使用這種方式
●   RetentionPolicy.RUNTIME : 始終不會丟棄,運行期也保留該注解,因此可以使用反射機制讀取該注解的信息。我們自定義的注解通常使用這種方式。

 

  2.)Target – 表示該注解用於什么地方。默認值為任何元素,表示該注解用於什么地方。可用的ElementType 參數包括

 ● ElementType.CONSTRUCTOR: 用於描述構造器
 ● ElementType.FIELD: 成員變量、對象、屬性(包括enum實例)
 ● ElementType.LOCAL_VARIABLE: 用於描述局部變量
 ● ElementType.METHOD: 用於描述方法
 ● ElementType.PACKAGE: 用於描述包
 ● ElementType.PARAMETER: 用於描述參數
 ● ElementType.TYPE: 用於描述類、接口(包括注解類型) 或enum聲明

 

 3.)@Documented – 一個簡單的Annotations 標記注解,表示是否將注解信息添加在java 文檔中。

 4.)@Inherited – 定義該注釋和子類的關系
  @Inherited 元注解是一個標記注解,@Inherited 闡述了某個被標注的類型是被繼承的。

  如果一個使用了@Inherited 修飾的annotation 類型被用於一個class,則這個annotation 將被用於該class 的子類。

 

自定義注解類的聲明

@Target(value= {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD}) 用於聲明當前注解類的作用范圍分別為 類 方法 屬性

@Retention(value = RetentionPolicy.RUNTIME) 運行時保留該注解,可以通過反射讀取注解信息

package com.gaunyi.batteryonline.annotation;

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

/**
 * Created by S0111 on 2019/8/20.
 * 自定義注解類聲明
 */
@Target(value= {ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@Retention(value = RetentionPolicy.RUNTIME)
public @interface MyAnnotationDefinition {

  /*定義注解里面的參數信息*/ String name(); String value(); String path(); }

 

自定義注解使用

分別在類、方法、屬性上使用注解信息

package com.gaunyi.batteryonline.annotation;

/**
 * Created by S0111 on 2019/8/20.
 * 自定義注解類使用
 */
@MyAnnotationDefinition(name="類名稱",value="類值",path="類路徑")
public class MyAnnotationUse {

    @MyAnnotationDefinition(name="屬性名",value="屬性值",path="屬性路徑")
    private String name;

    @MyAnnotationDefinition(name="年齡",value="18",path="/user2")
    private String age;

    @MyAnnotationDefinition(name="方法名",value="方法值",path="方法訪問路徑")
    public String testAnno(){
        return "successs!!!";
    }

    @MyAnnotationDefinition(name="方法名1",value="方法值1",path="方法訪問路徑1")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }
}

 

讀取注解信息(測試注解類)

這里通過反射讀取注解信息,注解內容與對應的類、方法、屬性對應。

package com.gaunyi.batteryonline.annotation;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * Created by S0111 on 2019/8/20.
 * 自定義注解類測試
 */
public class MyAnnotationTest {

    public static void  main(String[] args) throws Exception{
        Class clazz = Class.forName("com.gaunyi.batteryonline.annotation.MyAnnotationUse");

        //獲取類注解信息
        MyAnnotationDefinition classAnno =(MyAnnotationDefinition) clazz.getAnnotation(MyAnnotationDefinition.class);
        System.out.println( classAnno.name()+"---"+classAnno.value()+"---"+classAnno.path());

        //獲取所以方法注解信息 ps:這里需要使用 isAnnotationPresent 判斷方法上是否使用了注解
        Method[] allMethods = clazz.getDeclaredMethods();
        for(int i=0;i<allMethods.length;i++){
            if(allMethods[i].isAnnotationPresent(MyAnnotationDefinition.class)) {
                MyAnnotationDefinition methodAnno = allMethods[i].getAnnotation(MyAnnotationDefinition.class);
                System.out.println("遍歷:當前方法名為:"+allMethods[i].getName()+" 的注解信息:---"+methodAnno.name() + "---" + methodAnno.value() + "---" + methodAnno.path());
            }
        }

        //獲取指定方法注解信息
       Method methodTest = clazz.getDeclaredMethod("testAnno");
        MyAnnotationDefinition methodAnnotest =  methodTest.getAnnotation(MyAnnotationDefinition.class);
        System.out.println( methodAnnotest.name()+"---"+methodAnnotest.value()+"---"+methodAnnotest.path());


        //獲取屬性注解信息
        Field nameField =  clazz.getDeclaredField("name");
        MyAnnotationDefinition attrAnno = nameField.getAnnotation(MyAnnotationDefinition.class);
        System.out.println( attrAnno.name()+"---"+attrAnno.value()+"---"+attrAnno.path());
    }
}

  

測試結果

至此我們就實現了自定義注解啦....  關於自定義注解的實際應用,待我使用時再來更新...

 

關於注解的實際應用請參考此博客(通過注解標識注入相應日志信息):https://www.cnblogs.com/DFX339/p/12875544.html 

 


免責聲明!

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



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