Java注解解析原理在于“谁定义、谁保留、谁读取、谁处理”:注解本质是继承Annotation的接口,@Retention决定生命周期,反射是运行时唯一读取方式,真正起作用的是APT或Spring等外部处理器。

注解本质是接口,不是类
自定义注解 @MyLog 编译后生成的是 MyLog.class,它是一个继承 java.lang.annotation.Annotation 的接口,不是普通类。JVM 运行时通过动态代理生成其实例——这点常被误认为是“编译生成类”,实际是运行时代理对象。
@Retention 决定注解能活到什么时候
没有这个元注解,注解默认只保留在源码阶段(RetentionPolicy.SOURCE),反射根本拿不到。常见取值:
-
SOURCE:仅编译期有效,如@Override -
CLASS:写入 class 文件但不加载进 JVM,APT 工具可用 -
RUNTIME:加载进 JVM,可通过反射获取,Spring 大量依赖此级别
反射是运行时读取注解的唯一标准方式
只要注解声明为 @Retention(RetentionPolicy.RUNTIME),就能用反射拿到:
-
clazz.isAnnotationPresent(MyLog.class)—— 判断是否存在 -
clazz.getAnnotation(MyLog.class)—— 获取注解实例 -
method.getAnnotations()或field.getAnnotation(NotNull.class)—— 按需提取
真正起作用的是处理器,不是注解本身
注解只是标签,不执行任何逻辑。它的行为由外部机制驱动:
立即学习“Java免费学习笔记(深入)”;
- 编译期:APT(Annotation Processing Tool)配合
javax.annotation.processing.Processor,生成代码(如 ButterKnife、Lombok) - 运行期:框架(如 Spring)在启动时扫描 Bean,发现
@Service就注册为组件;AOP 拦截@Transactional方法做事务增强


















