Java自定义注解的底层实现与解析分为三步:定义(@interface声明,受元注解约束)、使用(标注在类/方法/字段上)、运行时通过反射(getAnnotation等)读取并由用户代码触发逻辑。

Java 自定义注解的底层实现与解析,核心在于三部分:定义注解(@interface)、在代码中使用、通过反射(Class/Method/Field#getAnnotation() 或 getAnnotations())读取并处理。它本身不带逻辑,真正的“行为”由使用者(如框架或你自己的工具类)在运行时通过反射 + 条件判断来触发。
自定义注解怎么写(声明层面)
用 @interface 关键字定义,本质是继承了 java.lang.annotation.Annotation 的特殊接口:
- 只能定义方法,不能有参数、不能有 throws、不能有方法体;返回类型只能是基本类型、String、Class、枚举、其他注解,或以上类型的数组
- 可设默认值(
default "xxx"),未显式赋值时取默认值 - 必须用元注解(meta-annotation)标明作用范围和生命周期,最常用的是:
@Target:指定能用在哪(如ElementType.METHOD、ElementType.TYPE)
@Retention:指定保留策略(RetentionPolicy.RUNTIME才能通过反射读取)
@Documented(可选):是否包含进 Javadoc
@Inherited(可选):是否被子类继承(仅对类注解生效)
注解怎么被读取和解析(运行时)
只有 @Retention(RetentionPolicy.RUNTIME) 的注解才能在运行时通过反射获取。关键操作是调用 getAnnotation(Class 或 isAnnotationPresent(Class:
- 类上注解:`clazz.getAnnotation(MyAnnotation.class)`
- 方法上注解:`method.getAnnotation(MyAnnotation.class)`
- 字段上注解:`field.getAnnotation(MyAnnotation.class)`
- 获取所有注解:`element.getAnnotations()`(含重复注解需配合
@Repeatable) - 注意:反射获取的是注解接口的代理实例,调用其方法会返回你设置的值(包括默认值)
如何让注解“起作用”(实际应用逻辑)
注解本身不会自动执行任何代码。你需要自己写解析逻辑,常见模式:
- 扫描 + 反射 + 判断 + 执行:遍历指定包下的类 → 获取类/方法/字段 → 检查是否有某注解 → 有则调用对应处理逻辑(如打印日志、修改行为、生成代理等)
-
结合 AOP(如 Spring):用
@Aspect切到带自定义注解的方法上,在通知(Advice)里做增强 -
编译期处理(APT):用
javax.annotation.processing.Processor在编译时生成代码(如 ButterKnife、Lombok 部分能力),不依赖反射,性能更好 - 运行时动态代理:检测到注解后,为对象创建代理(JDK Proxy / CGLIB),在代理逻辑中注入注解语义
一个极简可运行示例
定义注解:
@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)
public @interface LogExecutionTime { }
使用:
public class UserService {@LogExecutionTime
public void doWork() { Thread.sleep(1000); }
}
解析执行(手动反射):
Method m = UserService.class.getDeclaredMethod("doWork");if (m.isAnnotationPresent(LogExecutionTime.class)) {
long start = System.currentTimeMillis();
m.invoke(new UserService());
System.out.println("耗时: " + (System.currentTimeMillis() - start));
}
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











