Как вызвать метод getter, например, который находится внутри другого экземпляра

#java #reflection

#java #отражение

Вопрос:

У меня есть несколько классов, подобных приведенным ниже:

 @Getter
@Setter
class Person{
    @JsonProperty("cInfo")
    private ContactInformation contactInfo;
    private String name;
    private String position;
}

@Getter
@Setter
class ContactInformation{
    @JsonProperty("pAddress")
    private Address address;
}

@Getter
@Setter
class Address{
    private String street;
    private String district;
}
  

И что я собираюсь сделать, так это написать метод Utils для объекта Person, который принимает один параметр, который является attributeName, в виде строки и возвращает значение getter для этого атрибута.

Пример:

 attributeName = name -> return person.getName() 
attributeName = position -> return person.getPosition() 
attributeName = cInfo.pAddress.street -> return person.getContactInfo().getAddress().getStreet() 
attributeName = cInfo.pAddress.district -> return person.getContactInfo().getAddress().getDistrict()
  

Ниже приведено то, что я сделал: я перебираю все поля в объекте Person и проверяю, равно ли attributeName имени JsonProperty или имени поля, затем я верну этот метод получения.

 Object resu<
Field[] fields = Person.class.getDeclaredFields();
for (Field field : fields) {
    JsonProperty jsonProperty = field.getDeclaredAnnotation(JsonProperty.class);
    if (jsonProperty != null amp;amp; jsonProperty.value().equals(attributeName)) {
        result = Person.class.getMethod("get"   capitalize(field.getName())).invoke(person);
    } else {
        if (field.getName().equals(attributeName)) {
            result = person.class.getMethod("get"   capitalize(field.getName()))
                    .invoke(person);
        }
    }
}
  

Это сработало, но только с полями, которые находятся непосредственно в классе Person, например: name, position. С полями внутри ContactInfo или address я все еще застреваю там. Кто-нибудь может дать мне подсказку, как я могу это сделать?

Спасибо!

Комментарии:

1. docs.spring.io/spring-framework/docs/current/javadoc-api/org /… может решить вашу проблему

Ответ №1:

Потому что path like a.b.c относится к разным объектам. Итак, вам нужно. разделить по точкам и для каждого вызова токена получить и использовать полученный результат для следующего токена

ОБНОВЛЕНИЕ: что-то вроде:

 private static Object invkGen(Object passedObj, String attributeName) throws Exception {
    final String[] split = attributeName.split("\.");
    Object result = passedObj;
    for (String s : split) {
        if (result == null) {
            break;
        }
        result = invk(result, s);
    }
    return resu<
}

private static Object invk(Object passedObj, String attributeName) throws Exception {
    Object result = null;
    final Field[] fields = passedObj.getClass().getDeclaredFields();

    for (Field field : fields) {
        JsonProperty jsonProperty = field.getDeclaredAnnotation(JsonProperty.class);
        if (jsonProperty != null amp;amp; jsonProperty.value().equals(attributeName)) {
            result = Person.class.getMethod("get"   capitalize(field.getName())).invoke(passedObj);
        } else {
            if (field.getName().equals(attributeName)) {
                result = passedObj.getClass().getMethod("get"   capitalize(field.getName()))
                    .invoke(passedObj);
            }
        }
    }
    return resu<
}