You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 17中RecordComponent为何无法获取Records类上定义的注解信息?

问题结论

这个现象是完全符合Java规范的预期行为,你的预期偏差是对Record组件上的注解传播规则不了解导致的。

核心原因

Java在处理Record组件上的注解时,会根据注解本身的@Target配置,自动将注解传播到对应的生成元素上:

  • 如果注解的@Target包含ElementType.FIELD:注解会被写到生成的私有final成员字段上
  • 如果注解的@Target包含ElementType.METHOD:注解会被写到生成的公共访问器方法上
  • 如果注解的@Target包含ElementType.RECORD_COMPONENT:注解才会被写到RecordComponent元数据中,你通过recordComponents[x].isAnnotationPresent才能读到

你用到的@NotEmpty注解(无论是javax.validation还是jakarta.validation版本),默认的@Target配置通常只包含FIELD、METHOD、PARAMETER、ANNOTATION_TYPE、TYPE_USE,没有包含Java 16才新增的RECORD_COMPONENT类型,所以自然不会被记录到RecordComponent上。

验证示例

你可以用下面的自定义注解做测试,就能看到两边都返回true:

import java.lang.annotation.*;

@Target({ElementType.FIELD, ElementType.RECORD_COMPONENT})
@Retention(RetentionPolicy.RUNTIME)
@interface TestAnno {}

// 定义Record
record R(@TestAnno Integer i) {}

// 测试代码
public static void main(String[] args) {
    // 返回true
    System.out.println(R.class.getRecordComponents()[0].isAnnotationPresent(TestAnno.class));
    // 返回true
    System.out.println(R.class.getDeclaredFields()[0].isAnnotationPresent(TestAnno.class));
}

补充说明

如果你希望@NotEmpty这类校验注解同时能在RecordComponent上被读取到,需要自定义扩展校验注解,给它加上RECORD_COMPONENT的Target配置即可。

内容的提问来源于stack exchange,提问作者Dmitriy Dumanskiy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 06:36:00