Подтвердить что ты не робот

Получить все поля (даже частные и унаследованные) из класса

Я делаю университетский проект.
Мне нужно получить все поля из класса. Даже частные и унаследованные. Я попытался получить все объявленные поля, а затем бросил суперкласс и повторил. Фрагмент моего кода:

private void listAllFields(Object obj) {
    List<Field> fieldList = new ArrayList<Field>();
    while (obj != null) {
        fieldList.addAll(Arrays.asList(obj.getClass().getDeclaredFields()));
        obj = obj.getClass().getSuperclass().cast(obj);
    }
    // rest of code

Но это не сработает. tmpObj после литья по-прежнему остается одним и тем же классом (не суперклассом).
Я буду признателен за любую помощь, как исправить проблему кастинга или как получить эти поля по-разному.

EDIT:

Проблема заключается не в получении доступа к полям, а в получении имен полей!
Я управляю этим способом:

private void listAllFields(Object obj) {
    List<Field> fieldList = new ArrayList<Field>();
    Class tmpClass = obj.getClass();
    while (tmpClass != null) {
        fieldList.addAll(Arrays.asList(tmpClass .getDeclaredFields()));
        tmpClass = tmpClass .getSuperclass();
    }
    // rest of code
4b9b3361

Ответ 1

obj = obj.getClass().getSuperclass().cast(obj);

Эта строка не делает то, что вы ожидаете от нее. Кастинг объекта фактически не меняет его, он просто говорит компилятору рассматривать его как нечто другое.

например. вы можете применить List к Collection, но он все равно останется списком.

Однако, переполнение суперклассов для доступа к полям отлично работает без кастинга:

Class<?> current = yourClass;
while(current.getSuperclass()!=null){ // we don't want to process Object.class
    // do something with current fields
    current = current.getSuperclass();
}

Кстати, если у вас есть доступ к Spring Framework, есть удобный метод для прокрутки полей класса и всех суперклассов:
ReflectionUtils.doWithFields(baseClass, FieldCallback)
(также см. предыдущий мой ответ: Доступ к приватным унаследованным полям через отражение в Java)

Ответ 2

getDeclaredFields() дает вам все поля этого класса, включая private ones.

getFields() дает вам все поля public этого класса и его суперклассы.

Если вам нужны методы суперкласса private/protected, вам придется многократно вызывать getSuperclass(), а затем вызвать getDeclaredFields() в объекте Super Class.

Ничего здесь не ясно объяснено в javadocs

Ответ 3

попробуйте эти

Как прочитать приватное поле в Java?

Возможно ли в Java доступ к закрытым полям через отражение.

Field.setAccessible(true) - это то, что вам нужно сделать, чтобы сделать его доступным через отражение

import java.lang.reflect.Field;

class B 
{
    private int i = 5;
}

public class A extends B 
{
    public static void main(String[] args) throws Exception 
    {
        A a = new A();
        Field[] fs = a.getClass().getSuperclass().getDeclaredFields();
        for (Field field : fs)
        {
            field.setAccessible(true);
            System.out.println( field.get( a ) );
        }
    }
}

Ответ 4

Чтобы получить поля суперкласса, используйте getSuperclass(). Оттуда вы можете получить поля суперкласса.

Ответ 5

ClassName obj  =  new ClassName();
Field field  =   ClassName.class.getDeclaredField  ("name of the field");
field.setAccessible   (true);
DataType value  =  (DataType) field.get  (obj);

Перед извлечением значения вы должны использовать setAccessible в true. Когда-то JVM не позволяет извлекать приватную переменную, это может привести к исключению безопасности.

Ответ 7

Вот метод, который я использую для получения всех полей объекта

private <T> List<Field> getFields(T t) {
        List<Field> fields = new ArrayList<>();
        Class clazz = t.getClass();
        while (clazz != Object.class) {
            fields.addAll(Arrays.asList(clazz.getDeclaredFields()));
            clazz = clazz.getSuperclass();
        }
        return fields;
    }

Ответ 8

Да, возможно использование Reflection.

В вашем коде Field.setAccessible(true);

Идите и изучите концепцию, но НЕ делайте этого: -)