自定義注解

自定義注解是 Java 高級(jí)特性,核心分為 3 步:定義注解 → 給注解加元注解 → 解析注解(讓注解生效)。

核心概念

注解本質(zhì):一個(gè)帶 @interface 的接口
元注解:給自定義注解加規(guī)則的注解(必須加)
@Target:注解能用在哪里(類、方法、字段等)
@Retention:注解保留到什么時(shí)候(源碼 / 編譯 / 運(yùn)行時(shí))
解析注解:通過(guò)反射讀取注解信息,讓注解真正生效

須掌握的 4 個(gè)元注解

image.png

實(shí)際業(yè)務(wù)場(chǎng)景

權(quán)限校驗(yàn):@RequiresAdmin
日志記錄:@LogOperation
參數(shù)校驗(yàn):@NotNull、@Length
接口限流:@RateLimit
自定義緩存:@MyCache

完整實(shí)現(xiàn)一(解釋注解)

  1. 定義自定義注解
import java.lang.annotation.*;

// 元注解:指定注解作用范圍(方法、字段、類)
@Target({ElementType.METHOD, ElementType.FIELD, ElementType.TYPE})
// 元注解:指定注解保留到運(yùn)行時(shí)(必須寫,否則反射讀不到)
@Retention(RetentionPolicy.RUNTIME)
// 自定義注解
public @interface MyAnnotation {
    // 定義注解屬性(默認(rèn)值可選)
    String value() default "默認(rèn)值";
    int age() default 18;
    boolean isCheck() default true;
}
  1. 使用自定義注解
// 作用在類上
@MyAnnotation(value = "測(cè)試類", age = 20)
public class TestClass {

    // 作用在字段上
    @MyAnnotation(value = "用戶名字段", isCheck = false)
    private String username;

    // 作用在方法上
    @MyAnnotation("登錄方法") // 只有value屬性可省略名稱
    public void login() {
        System.out.println("執(zhí)行登錄方法");
    }
}
  1. 解析注解(核心:反射實(shí)現(xiàn))
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class AnnotationParser {
    public static void main(String[] args) throws Exception {
        // 1. 獲取目標(biāo)類的Class對(duì)象
        Class<TestClass> clazz = TestClass.class;

        // ====================== 解析類上的注解 ======================
        if (clazz.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation classAnno = clazz.getAnnotation(MyAnnotation.class);
            System.out.println("類注解信息:");
            System.out.println("value = " + classAnno.value());
            System.out.println("age = " + classAnno.age());
        }

        // ====================== 解析字段上的注解 ======================
        Field field = clazz.getDeclaredField("username");
        if (field.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation fieldAnno = field.getAnnotation(MyAnnotation.class);
            System.out.println("\n字段注解信息:");
            System.out.println("value = " + fieldAnno.value());
            System.out.println("isCheck = " + fieldAnno.isCheck());
        }

        // ====================== 解析方法上的注解 ======================
        Method method = clazz.getDeclaredMethod("login");
        if (method.isAnnotationPresent(MyAnnotation.class)) {
            MyAnnotation methodAnno = method.getAnnotation(MyAnnotation.class);
            System.out.println("\n方法注解信息:");
            System.out.println("value = " + methodAnno.value());
        }
    }
}
  1. 運(yùn)行結(jié)果
類注解信息:
value = 測(cè)試類
age = 20

字段注解信息:
value = 用戶名字段
isCheck = false

方法注解信息:
value = 登錄方法
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容