java注解是为代码添加元数据的轻量级机制,需定义注解(用@interface及元注解如@target、@retention)、标记代码、编写解析逻辑三步协同;运行时通过反射读取(要求retentionpolicy.runtime),编译期可通过apt生成源码。

Java注解(Annotation)是为代码添加元数据的轻量级机制,本身不直接影响程序逻辑,但可通过反射在运行时读取,或通过APT在编译期处理。要真正发挥作用,需“定义注解 + 标记代码 + 编写解析逻辑”三步协同。
定义自定义注解
使用 @interface 声明注解类型,配合元注解控制其作用范围和生命周期:
-
@Target:指定可标注的位置(如
ElementType.METHOD、ElementType.TYPE) -
@Retention:指定保留策略(
RetentionPolicy.RUNTIME才能通过反射读取) - @Documented(可选):表示该注解应包含在 JavaDoc 中
- @Inherited(可选):允许子类继承父类的注解
例如定义一个用于标记接口实现类的注解:
<font size="2">@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Service {
String value() default "";
String version() default "1.0";
}</font>
在代码中使用注解
将注解加在类、方法、字段等目标上,支持传入参数(键值对形式):
<font size="2">@Service(value = "user-service", version = "2.1")
public class UserServiceImpl implements UserService {
// ...
}</font>
注意:若注解只有一个名为 value 的属性,使用时可省略名称,直接写 @Service("user-service")。
运行时解析注解(基于反射)
通过 Class.getAnnotation() 或 Method.getAnnotation() 等方法获取注解实例,再调用其方法提取元数据:
<font size="2">Class> clazz = UserServiceImpl.class;
Service serviceAnno = clazz.getAnnotation(Service.class);
if (serviceAnno != null) {
System.out.println("Name: " + serviceAnno.value());
System.out.println("Version: " + serviceAnno.version());
}</font>
常见场景包括:自动注册服务、权限校验、日志埋点、序列化控制等。关键点是确保注解声明为 RetentionPolicy.RUNTIME,否则反射无法获取。
编译期处理注解(APT)
若需生成新源码(如 ButterKnife、Lombok、MapStruct),可用注解处理器(AbstractProcessor)在编译阶段扫描并处理注解:
- 创建继承
AbstractProcessor的类,重写process() - 在
getSupportedAnnotationTypes()中声明支持的注解全限定名 - 使用
RoundEnvironment获取被标注的元素(Element),再通过Filer生成 .java 文件 - 将处理器打包为 jar,并在
META-INF/services/javax.annotation.processing.Processor中声明入口类
这种方式不依赖反射,性能更高,且能在编译时报错,适合框架级能力扩展。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











