497. Java 反射 - 使用反射读取注解

文章目录

  • [497. Java 反射 - 使用反射读取注解](#497. Java 反射 - 使用反射读取注解)
    • [1. 为什么要关心注解?](#1. 为什么要关心注解?)
    • [2. 获取注解的工具类:`AnnotatedElement`](#2. 获取注解的工具类:AnnotatedElement)
    • [3. 示例:类级别注解](#3. 示例:类级别注解)
    • [4. 示例:重复注解 (Repeatable Annotations)](#4. 示例:重复注解 (Repeatable Annotations))
      • [方式一:通过容器注解 `@Validators`](#方式一:通过容器注解 @Validators)
      • [方式二:直接用 `getAnnotationsByType()`](#方式二:直接用 getAnnotationsByType())
    • [5. 总结](#5. 总结)

497. Java 反射 - 使用反射读取注解

1. 为什么要关心注解?

在现代 Java 开发中,注解已经成为框架和库的"开关"。

  • ORM 框架(如 Hibernate、JPA):用注解标记实体字段和表的映射。
  • Spring:用注解实现依赖注入、事务管理、安全控制。
  • 验证框架:用注解标记参数是否允许 null、是否必须符合某种格式。

👉 注解之所以能发挥作用,核心原因就是:运行时通过反射 API 读取注解并执行相应逻辑。


2. 获取注解的工具类:AnnotatedElement

以下几个反射类都实现了 AnnotatedElement 接口:

  • Class(类、接口、枚举、记录、数组)
  • Field(字段)
  • Method(方法)
  • Constructor(构造函数)

它们提供了几组关键方法:

  • isAnnotationPresent(Class<?>):是否存在某个注解。
  • getAnnotations():获取该元素上的所有注解(包括继承的)。
  • getDeclaredAnnotations():只获取该元素本身声明的注解。
  • getAnnotation(Class<?>):获取指定类型的注解实例。
  • getAnnotationsByType(Class<?>):获取重复注解。

3. 示例:类级别注解

定义枚举和注解:

java 复制代码
enum SerializedFormat { BINARY, XML, JSON }

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Bean {}

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface Serialized {
    SerializedFormat format() default SerializedFormat.JSON;
}

在类上使用:

java 复制代码
@Serialized
@Bean
public class Person {}

通过反射读取:

java 复制代码
Class<?> c = Person.class;

boolean isBean = c.isAnnotationPresent(Bean.class);
System.out.println("isBean = " + isBean);

Annotation[] annotations = c.getAnnotations();
for (Annotation annotation : annotations) {
    System.out.println("annotation = " + annotation);
}

输出:

java 复制代码
isBean = true
annotation = @org.devjava.Serialized(format=JSON)
annotation = @org.devjava.Bean()

👉 注意:返回的其实是注解类的实例对象,你可以直接调用它的方法。

java 复制代码
Serialized serialized = c.getAnnotation(Serialized.class);
System.out.println("format = " + serialized.format());

输出:

java 复制代码
format = JSON

4. 示例:重复注解 (Repeatable Annotations)

定义验证规则:

java 复制代码
enum ValidationRules { NON_NULL, NON_EMPTY, NON_ZERO }

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface Validators {
    Validator[] value();
}

@Target(ElementType.FIELD)
@Repeatable(Validators.class)
@interface Validator {
    ValidationRules value();
}

应用在 Person 类的字段上:

java 复制代码
public class Person {
    @Validator(ValidationRules.NON_NULL)
    @Validator(ValidationRules.NON_EMPTY)
    private String name;
}

读取注解:

方式一:通过容器注解 @Validators

java 复制代码
Field nameField = Person.class.getDeclaredField("name");
Annotation[] annotations = nameField.getAnnotations();
Validators validators = (Validators) annotations[0];
for (Validator v : validators.value()) {
    System.out.println("validator = " + v);
}

输出:

java 复制代码
validator = @org.devjava.Validator(NON_NULL)
validator = @org.devjava.Validator(NON_EMPTY)

方式二:直接用 getAnnotationsByType()

java 复制代码
Validator[] validators = nameField.getAnnotationsByType(Validator.class);
for (Validator v : validators) {
    System.out.println("annotation = " + v);
}

输出:

java 复制代码
annotation = @org.devjava.Validator(NON_NULL)
annotation = @org.devjava.Validator(NON_EMPTY)

👉 第二种方式更简洁,JDK 会自动帮你展开容器注解。


5. 总结

  • 注解是框架的"说明书",框架通过反射读取注解来决定如何运行。
  • 类、方法、字段、构造函数 都可以携带注解,并通过 AnnotatedElement 访问。
  • isAnnotationPresent():检查是否存在。
  • getAnnotation():获取单个注解。
  • getAnnotationsByType():用于重复注解。
相关推荐
段一凡-华北理工大学4 小时前
工业智能体:从Codex/Claude到项目实战~系列文章05:从“AI助手“到“工业智能体“:能力跃迁与落地范式
人工智能·python·claude·codex·工业智能体·高炉炼铁智能化
独泪了无痕5 小时前
探索Pinyin4j-Java中的拼音转换利器
java·后端
深蓝AI5 小时前
ContextVar 到线程池就丢了?asyncio.to_thread 和 run_in_executor 实测
python
道尔柯南6 小时前
C++ string 类详解:从常用接口到深拷贝,彻底掌握字符串处理
android·java·c++
岁月宁静6 小时前
什么是 Agent:从"会聊天"到"会做事"
人工智能·python
岁月宁静6 小时前
AI 应用开发工程师简历怎么写:HR 初筛、技术复筛、面试追问,三道关卡各看什么?
人工智能·python·面试
来让爷抱一个7 小时前
Python 异步里混用同步库,事件循环被卡住的全过程
开发语言·python
kingx37 小时前
Bugku 3122 谷歌小恐龙题解:纯离线逆向 Vault 的 AES-GCM 加密资源(附 Python 解密器)
java·逆向·ctf·bugku·aes-gcm
小肝一下8 小时前
3.基础语法(3)
python
DevOpenClub9 小时前
职教高考控制线 API:招生类别枚举、筛选与空分数含义
java·数据库·高考