java 使用反射提取嵌套记录字段

plupiseo  于 2023-10-14  发布在  Java
关注(0)|答案(1)|浏览(96)

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 Person(Address address) {}
public record Address(String city) {}

var p = new Person(new Address("Malgudi"));

BeanUtils.getNestedProperty(p, "address.city"); // ❌ Unknown property 'address'
jaxagkaj

jaxagkaj1#

虽然我找不到一个可以在一行程序中实现这一点的通用库,但有一种方法可以在jackson-databind的帮助下配置BeanUtils来实现这一点:

//add support for Java records to Apache BeanUtils
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

相关问题