commons-beanutils可以从bean中检索嵌套值:
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
当数据类型是记录时,如何以类似紧凑的方式实现这一点?
BeanUtils
显然不支持记录:
public record Address(String city) {}
public record Person(Address address) {}
var p = new Person(new Address("Malgudi"));
BeanUtils.getNestedProperty(p, "address.city"); // ❌ Unknown property 'address'
虽然我找不到可以单行执行此操作的通用库,但有一种方法可以配置
BeanUtils
来在 jackson-databind 的帮助下实现此目的:
var utils = BeanUtilsBean.getInstance().getPropertyUtils();
utils.addBeanIntrospector(context -> {
var clazz = context.getTargetClass();
var recordFieldNames = JDK14Util.getRecordFieldNames(clazz); //helper method from jackson-databind
if (recordFieldNames == null) {
return;
}
for (String name : recordFieldNames) {
try {
var getter = clazz.getDeclaredMethod(name);
context.addPropertyDescriptor(new PropertyDescriptor(name, getter, null));
} catch (NoSuchMethodException ignored) {
//accessor method of record field not found (should not happen)
}
}
});
var p = new Person(new Address("Malgudi"));
utils.getNestedProperty(p, "address.city"); // ✅ Malgudi