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

Java 17下BeanUtils.getProperty对Record失效的替代方案咨询

Java 17 兼容普通类与Record的属性获取方案

当使用BeanUtils.getProperty()处理Record类型对象时失效,核心原因是Record没有传统JavaBean的getXxx()风格Getter,而是使用与组件同名的访问方法(比如record User(String name) {}的访问方法是name()),而BeanUtils的逻辑仅识别getXxx/isXxx格式的方法。以下是几个实用的替代方案:

1. 自定义兼容工具类

手动封装一个工具方法,通过反射判断对象类型,分别处理Record和普通类:

import java.lang.reflect.Method;
import java.lang.reflect.RecordComponent;
import org.apache.commons.beanutils.BeanUtils;

public class PropertyAccessor {
    public static Object getProperty(Object obj, String propertyName) throws Exception {
        Class<?> objClass = obj.getClass();
        if (objClass.isRecord()) {
            // 遍历Record组件,匹配属性名后调用访问方法
            for (RecordComponent component : objClass.getRecordComponents()) {
                if (component.getName().equals(propertyName)) {
                    return component.getAccessor().invoke(obj);
                }
            }
            throw new NoSuchFieldException("Record中不存在属性: " + propertyName);
        } else {
            // 普通类沿用BeanUtils原有逻辑
            return BeanUtils.getProperty(obj, propertyName);
        }
    }
}

2. 借助Spring BeanWrapper(Spring项目适用)

Spring的BeanWrapper组件已经原生支持Record类型,内部自动适配Record的访问方法与普通JavaBean的Getter,无需额外判断:

import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

public class PropertyAccessor {
    public static Object getProperty(Object obj, String propertyName) {
        BeanWrapper wrapper = new BeanWrapperImpl(obj);
        return wrapper.getPropertyValue(propertyName);
    }
}

3. 纯JDK反射实现(无第三方依赖)

如果项目不想引入额外依赖,可以直接用Java 17的反射API实现兼容逻辑:

import java.lang.reflect.Method;
import java.lang.reflect.RecordComponent;

public class PropertyAccessor {
    public static Object getProperty(Object obj, String propertyName) throws Exception {
        Class<?> clazz = obj.getClass();
        // 处理Record类型
        if (clazz.isRecord()) {
            for (RecordComponent rc : clazz.getRecordComponents()) {
                if (rc.getName().equals(propertyName)) {
                    return rc.getAccessor().invoke(obj);
                }
            }
        } else {
            // 处理普通JavaBean的getXxx方法
            String getterName = "get" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
            try {
                Method getter = clazz.getMethod(getterName);
                return getter.invoke(obj);
            } catch (NoSuchMethodException e) {
                // 布尔类型尝试isXxx方法
                getterName = "is" + Character.toUpperCase(propertyName.charAt(0)) + propertyName.substring(1);
                Method isGetter = clazz.getMethod(getterName);
                return isGetter.invoke(obj);
            }
        }
        throw new IllegalArgumentException("未找到属性: " + propertyName);
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 11:47:16