Получение значений вложенных полей (полей поля типа объекта) с использованием отражения Java - PullRequest
2 голосов
/ 03 июня 2019

Есть класс, некоторые из его полей являются пользовательскими объектами. Я собираюсь:

  1. Получить поля первичного класса и пройти через них, чтобы получить их значения.

    1.1 При обнаружении поля с типом объекта, пройти через этот объект, который имеет свои собственные поля

  2. Получить значения этих вложенных полей (полей поля типа объекта)

Проблема на шаге 2; Когда я получаю поля поля объекта, я не могу получить их значения, так как мне нужно передать объект в field.get(object), чтобы указать, из какого объекта я хочу получить значения полей, из которых извлекаются, но как я могу получить доступ к текущему объекту? нашего разговорного поля с типом объекта?

Вот код:

public class PrimaryClass {
    String str;
    int num;
    MyClass cls;
}


PrimaryClass primaryObject = new PrimaryClass();

Field[] primaryObjectFields = primaryObject.getClass().getDeclaredFields();

// ... One of the fields is :  MyClass foo.bar.cls
// Assuming stored with name of clsField 

Field[] myClassObjectFields = clsField.getType().getDeclaredFields();

for (Field f : myClassObjectFields) {

    String fieldValue = f.get(primaryObject /* What to pass here? */); 
    // !!!! The above line Doesn't work since the primary Object doesn't have access to its child's fields

    System.out.println(fieldValue);

}

Когда я получаю поле первого уровня (и устанавливаю его доступным с помощью setAccessible(true)), чтобы получить его поле внутреннего объекта, я называю это:

topLevelField.getClass().getDeclaredField("details"); 
topLevelField.setAccessible(true);
topLevelField.get(primaryObject);

Но не удалось получить доступ к полю объекта, которое создается внутри родительского объекта, и получить эту ошибку:

java.lang.IllegalArgumentException: Can not set java.util.List field com.foo.Bar.details to com.foo.Bar

Внутренний объект - это List объектов, но в некоторых случаях он может быть и списочным объектом.

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Вот классное руководство , которое поможет вам начать работу.в общем, get возвращает вам объект, а затем вы можете привести его к тому типу, который вам нуженКроме того, вы можете спросить поле для его типа, и сделать некоторую логику в соответствии с типом поля.Есть также классные методы, которые лучше для вас, чтобы ознакомиться с clazz.isAssignableFrom(obj.getClass())

, вы можете прочитать больше об этом здесь

0 голосов
/ 17 июня 2019

Чтобы вызвать field.get(instance), вам нужен экземпляр instance типа, который объявляет поле.Таким образом, для каждого уровня вложенности, для которого вы получаете список полей, вам также необходимо получить соответствующий список значений полей.Это проще объяснить без цикла, но как только он будет работать для первого поля на каждом уровне вложенности, будет легко воссоздать итерацию из приведенного ниже примера, который предполагает следующую адаптированную структуру для простоты:

class PrimaryClass {
    MyClass cls = new MyClass();
    String str = "foo";
}

class MyClass {
    String value= "test";
}

На верхнем уровне у нас есть ваш основной экземпляр:

PrimaryClass primaryObject = new PrimaryClass();
Field[] primaryObjectFields = primaryObject.getClass().getDeclaredFields();

Для обработки первого поля мы получаем и тип поля и его значение:

Class<?> primaryObjectField1Type = primaryObjectFields[0].getType();
Object primaryObjectField1Value = primaryObjectFields[0].get(primaryObject);

Обратите внимание, как получить значение поля, нам нужно было передать ссылку на экземпляр (primaryObject) класса, который объявил поля primaryObjectFields.Мы просто делаем это для каждого уровня вложенности:

Field[] myClassObjectFields = primaryObjectField1Type.getDeclaredFields();

Class<?> myClassObjectField1Type = myClassObjectFields[0].getType();
Object myClassObjectField1Value = myClassObjectFields[0].get(primaryObjectField1Value);

Обратите внимание, как теперь экземпляр, который мы передаем для получения, равен primaryObjectField1Value, который является экземпляром MyClass, который объявляет поле value.

В общем, решение вашей проблемы состоит в том, чтобы получить значения полей вместе с их типом и передать эти значения в Field.get.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...