Java-元注解 (Meta-Annotations)

1. @Target(ElementType.METHOD)

作用:规定注解的使用位置。

  • 含义 :这行代码限制了你的自定义注解只能标记在方法(Method)上

  • 效果:如果你尝试把这个注解加在类(Class)、字段(Field)或者包(Package)上,编译器会直接报错。

常见的 ElementType 类型:

  • METHOD:只能用于方法。

  • TYPE:用于类、接口、枚举。

  • FIELD:用于成员变量。

  • PARAMETER:用于方法参数。

举例: 就像是给一张贴纸印上了"仅限贴在门把手上",如果你贴在窗户上就是违规的。


2. @Retention(RetentionPolicy.RUNTIME)

作用:规定注解的生命周期(存活时间)。

  • 含义 :这行代码表示你的注解会一直保留到程序运行期间 (Runtime)

  • 核心用途 :这是最关键的一点。只有设置为 RUNTIME,程序才能在运行时通过反射 (Reflection) 机制读取到这个注解。如果不加这一行(或者设为其他值),你的代码跑起来的时候,这个注解就已经"消失"了,程序无法检测到它。

RetentionPolicy 的三个阶段对比:

策略 (Policy) 存活范围 说明 典型应用
SOURCE 源码阶段 编译成 .class 文件后就被丢弃了。 @Override, @SuppressWarnings
CLASS (默认) 字节码阶段 存在于 .class 文件中,但 JVM 加载运行时会忽略它。反射拿不到。 Lombok, 编译时处理工具
RUNTIME 运行阶段 一直存在于 JVM 中,可以通过反射动态获取。 Spring AOP, 自定义拦截器

举例: 就像你写了一张便利贴:

  • SOURCE:看完就扔进垃圾桶。

  • CLASS:夹在书里存进了档案室,但平时工作时不拿出来看。

  • RUNTIME:贴在电脑屏幕边框上,随时干活随时看(程序运行时随时读取)。


3. 实际应用场景:AOP 与 拦截器

当你把这两个注解结合在一起时,通常是为了实现 AOP(面向切面编程)拦截器 功能。

代码示例:一个用于记录日志的自定义注解

java 复制代码
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 1. 定义注解:只能用在方法上,且运行时可通过反射读取
@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME)
public @interface MyLog {
    String value() default "";
}

如何使用:

java 复制代码
public class UserService {

    // 2. 正确使用:标记在方法上
    @MyLog("记录用户登录操作") 
    public void login() {
        System.out.println("用户正在登录...");
    }
    
    // 错误使用:如果把 @MyLog 加在字段上,编译器会报错,因为 @Target 限制了只能是 METHOD
    // @MyLog 
    // private String name; 
}

程序运行时(Spring AOP 或 反射)的逻辑:

  1. 程序运行到 login() 方法。

  2. 通过反射检查 login() 方法头上有没有 @MyLog 注解。

  3. 因为是 RUNTIME,所以能扫描到。

  4. 读取注解里的内容("记录用户登录操作"),然后自动执行写日志的代码。


4.总结

  • @Target(ElementType.METHOD) :划定界限,告诉编译器这个标签只能贴在方法上

  • @Retention(RetentionPolicy.RUNTIME) :延长寿命,告诉 JVM 程序运行时不要丢掉这个标签,因为我们的逻辑代码(如拦截器)需要读取它。

相关推荐
Meteors.2 小时前
安卓进阶——原理机制
android·java·开发语言
是阿漂啊2 小时前
vscode运行springboot项目
java·spring boot·后端
ghfdgbg2 小时前
13. 配置优先级 + Bean的管理 + SpringBoot核心原理
java·spring boot·后端
Moe4882 小时前
Elasticsearch 8.1 Java API Client 客户端使用指南(索引、文档操作篇)
java·后端·面试
洋亦2 小时前
GoF23种设计模式 简介
java
Javatutouhouduan2 小时前
Java面试常问Redis核心知识点整理!
java·数据库·redis·java面试·后端开发·java架构师·java程序员
AAA简单玩转程序设计2 小时前
谁说Java枚举只是“常量装盒”?它藏着这些骚操作
java·前端
枯基Evan2 小时前
applicationTaskExecutor Spring 内置线程池失效
java·数据库·spring
优爱蛋白2 小时前
IL-21:后Th1/Th2时代的免疫新星
java·服务器·前端·人工智能·健康医疗