如何以简洁方式提取Java Record嵌套字段?BeanUtils不支持该类型
Java Record 嵌套属性读取的实现方案
commons-beanutils 可以轻松从JavaBean中读取嵌套属性值:
public class Person { Address address; public Address getAddress() { return address; } } public class Address { String city; public String getCity() { return city; } } var p = new Person(); p.address = new Address(); p.address.city = "Malgudi"; BeanUtils.getNestedProperty(p, "address.city"); // ✅ 返回 Malgudi
但当使用Java Record时,BeanUtils并不支持这种嵌套属性读取:
public record Person(Address address) {} public record Address(String city) {} var p = new Person(new Address("Malgudi")); BeanUtils.getNestedProperty(p, "address.city"); // ❌ 报错:Unknown property 'address'
以下是几种简洁的替代实现方案:
方案1:使用Jackson ObjectMapper
Jackson原生支持Java Record,可通过JSON节点路径读取嵌套属性:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.JsonNode; public class RecordNestedDemo { public static void main(String[] args) throws Exception { var p = new Person(new Address("Malgudi")); ObjectMapper mapper = new ObjectMapper(); // 方式1:转换为JsonNode后逐层读取 JsonNode rootNode = mapper.valueToTree(p); String city = rootNode.get("address").get("city").asText(); // ✅ Malgudi // 方式2:使用JSON路径直接定位 String cityPathValue = mapper.readValue(mapper.writeValueAsString(p), JsonNode.class) .at("/address/city").asText(); } }
方案2:使用Spring BeanWrapper
Spring的BeanWrapper组件兼容Java Record,支持通过属性路径直接取值:
import org.springframework.beans.BeanWrapper; import org.springframework.beans.BeanWrapperImpl; public class RecordNestedDemo { public static void main(String[] args) { var p = new Person(new Address("Malgudi")); BeanWrapper wrapper = new BeanWrapperImpl(p); String city = (String) wrapper.getPropertyValue("address.city"); // ✅ Malgudi } }
方案3:自定义轻量反射工具类
如果不想引入第三方依赖,可利用Record自动生成的访问方法(属性名())实现工具类:
import java.lang.reflect.Method; public class RecordPropertyUtils { public static Object getNestedProperty(Object record, String path) throws Exception { String[] props = path.split("\\."); Object current = record; for (String prop : props) { Method accessor = current.getClass().getMethod(prop); current = accessor.invoke(current); if (current == null) return null; } return current; } public static void main(String[] args) throws Exception { var p = new Person(new Address("Malgudi")); String city = (String) getNestedProperty(p, "address.city"); // ✅ Malgudi } }
内容的提问来源于stack exchange,提问作者Knight Industries
相关产品推荐
相关产品推荐

