注解本质是JVM特殊处理的接口,隐式继承自java.lang.annotation.Annotation;其运行时实例为AnnotationInvocationHandler代理对象,通过元注解(@Retention、@Target等)定义行为,接口本身仅提供统一契约。

注解(Annotation)本质上是一种特殊的接口,它在 Java 中被定义为 interface,但由 JVM 特殊处理。所有注解类型都隐式继承自 java.lang.annotation.Annotation 接口——这是注解体系的根接口,也是唯一一个所有注解的公共父接口。
Annotation 是接口,但不是普通接口
当你写 @interface MyAnno,编译器会生成一个继承自 java.lang.annotation.Annotation 的接口类(字节码层面),并自动添加 public abstract 修饰符到每个方法声明上。这个接口不能被显式实现或继承(不能 extends Annotation),也不能用 new 实例化。它的实例由 JVM 在运行时动态代理生成,实际是 AnnotationInvocationHandler 的代理对象。
java.lang.annotation.Annotation 接口的核心作用
该接口本身只定义了 5 个方法,全部来自 Object(如 toString()、equals()、hashCode())和一个关键方法:
-
annotationType():返回该注解的实际类型(即Class<? extends Annotation>),是区分不同注解的底层依据 - JVM 通过反射获取注解时,最终返回的是实现了该接口的动态代理实例,其行为由
AnnotationInvocationHandler控制 - 该接口不包含任何业务语义,纯粹是运行时识别与统一操作的契约
注解的元注解体系支撑其行为
真正决定注解“怎么用”的,是作用在注解之上的元注解(meta-annotations),它们本身也是注解,且都实现了 Annotation 接口:
-
@Retention:控制注解保留策略(SOURCE / CLASS / RUNTIME) -
@Target:限定注解可标注的位置(如 METHOD、FIELD、TYPE) -
@Documented:标记注解是否应被 javadoc 记录 -
@Inherited:允许注解被子类继承(仅对类生效)
这些元注解的存在,使得 Annotation 接口能承载丰富的元数据语义,而无需修改其自身定义。
底层实现关键:AnnotationInvocationHandler
当通过反射(如 method.getAnnotation(MyAnno.class))获取注解实例时,JVM 返回的并非真实类对象,而是:
- 一个基于
Proxy和AnnotationInvocationHandler构建的动态代理 -
AnnotationInvocationHandler内部持有注解属性名值对的Map<String, Object> - 每次调用注解方法(如
myAnno.value())都会触发invoke(),从 map 中取值并做类型检查与默认值填充
这种设计既保证了注解的不可变性与轻量性,又支持了灵活的属性访问和默认值机制。

















