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

Java 17中如何通过反射获取Record类型的所有字段及对应值?

问题原因

Record类型的所有组件对应字段均为隐式private final修饰,Class.getFields()方法仅返回类中声明为public的字段,因此调用后会拿到空数组。Java 16及以上版本为Record类型提供了专用的反射API,是处理该场景的首选方案。

正确实现方式

方案1:使用Record专用反射API(推荐)

该方案符合Record的设计规范,无需处理访问权限,不受Java模块化系统的封装限制,兼容性最优。
示例代码如下:

Object obj = // 你的Record实例
if (obj.getClass().isRecord()) {
    // 获取该Record类型的所有组件
    RecordComponent[] components = obj.getClass().getRecordComponents();
    for (RecordComponent component : components) {
        // 获取组件名称(对应你定义Record时的参数名)
        String fieldName = component.getName();
        // 调用组件的访问器方法获取对应值
        Object fieldValue = component.getAccessor().invoke(obj);
        // 此处插入你原有校验逻辑即可
    }
} else {
    // 普通类走原有逻辑
    Field[] fields = obj.getClass().getFields();
    for (Field field : fields) {
        // 原有校验逻辑
    }
}

方案2:沿用Field API兼容旧逻辑

如果你的校验逻辑高度依赖Field类型,不想做大规模改造,可以用getDeclaredFields()替代getFields(),手动开启访问权限即可:

Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
    // 过滤静态字段,仅保留Record对应的实例字段
    if (Modifier.isStatic(field.getModifiers())) {
        continue;
    }
    // 开启private字段的访问权限
    field.setAccessible(true);
    Object fieldValue = field.get(obj);
    // 此处插入原有校验逻辑即可
}
方案对比
  • 优先选择RecordComponent方案:API是官方专门为Record设计的,不会随JDK实现细节变化而失效,也不需要处理权限相关的兼容问题。
  • Field方案仅适合临时兼容旧代码:Record的字段属于隐式生成的内部实现,后续JDK版本可能调整生成规则,存在兼容性风险。

内容的提问来源于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 05:15:02