java注解本质是继承annotation接口的元数据,生命周期由@retention决定:source仅存于源码、class保留在字节码但运行时不可反射获取、runtime唯一支持反射读取,需配合@target等元注解约束使用场景。

注解的本质:不是语法糖,是运行时可读的元数据
别再把它当成编译器“看一眼就扔”的装饰。一个 @Retention(RUNTIME) 的注解,会被 JVM 写进字节码的 RuntimeVisibleAnnotations 属性里,类加载时存入方法区——这意味着它真实存在于运行时内存中,能被反射精准读取。而 @Override 这类 SOURCE 级注解,编译完就彻底消失;CLASS 级则只留到字节码,JVM 加载时不保留。理解这个分层,才能判断“为什么我用反射拿不到这个注解”。
注解的约束:靠元注解定边界,不是想标哪就标哪
自定义注解必须配 @Target 和 @Retention,否则就是“裸奔”。比如:
Java Maven 项目审查工作流的通用输入处理。当 Java Maven 项目以 ZIP压缩包或 GitLab 仓库 URL 形式提供且需要...时使用。
- @Target({METHOD, FIELD}) —— 表示只能标在方法或字段上,标到类上直接编译报错
- @Retention(RUNTIME) —— 决定能不能用反射读取;若只写 @Retention(CLASS),Spring AOP 就抓不到它
- 属性命名有讲究:value() 是默认键,单属性时可省略写法(如 @MyLog("info"));其他属性必须显式赋值(如 @MyLog(level="warn", module="auth"))
注解的生效:分编译期和运行时两条路径
注解本身不执行任何逻辑,它只是信息载体。真正干活的是背后的处理器:
- 编译期处理(APT):Lombok 的 @Data 就是典型——javac 编译时调用注解处理器,动态生成 getter/setter/toString 方法,字节码里真有这些方法
- 运行时处理(反射):Spring 的 @Autowired 在 IOC 容器启动时扫描 Bean,通过 Class.getDeclaredMethods() + method.getAnnotation(Autowired.class) 找到注入点,再完成依赖装配
- 别混淆概念:@Transactional 看似“自动生效”,实则是 Spring AOP 基于代理+反射+注解解析实现的,不是注解自己在执行事务
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










