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 程序运行时不要丢掉这个标签,因为我们的逻辑代码(如拦截器)需要读取它。

相关推荐
皮皮林5519 小时前
Java性能调优黑科技!1行代码实现毫秒级耗时追踪,效率飙升300%!
java
冰_河9 小时前
QPS从300到3100:我靠一行代码让接口性能暴涨10倍,系统性能原地起飞!!
java·后端·性能优化
桦说编程12 小时前
从 ForkJoinPool 的 Compensate 看并发框架的线程补偿思想
java·后端·源码阅读
躺平大鹅14 小时前
Java面向对象入门(类与对象,新手秒懂)
java
初次攀爬者15 小时前
RocketMQ在Spring Boot上的基础使用
java·spring boot·rocketmq
花花无缺15 小时前
搞懂@Autowired 与@Resuorce
java·spring boot·后端
Derek_Smart16 小时前
从一次 OOM 事故说起:打造生产级的 JVM 健康检查组件
java·jvm·spring boot
NE_STOP17 小时前
MyBatis-mybatis入门与增删改查
java
孟陬20 小时前
国外技术周刊 #1:Paul Graham 重新分享最受欢迎的文章《创作者的品味》、本周被划线最多 YouTube《如何在 19 分钟内学会 AI》、为何我不
java·前端·后端