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

Отражение Java получает все частные поля

Интересно, есть ли способ получить все частные поля некоторого класса в java и их тип.

Например, допустим, что у меня есть класс

class SomeClass {
    private String aaa;
    private SomeOtherClass bbb;
    private double ccc;
}

Теперь я хотел бы получить все частные поля (aaa, bbb, ccc) класса SomeClass (не зная имя всех полей upfront) и проверить их тип.

4b9b3361

Ответ 1

Можно получить все поля с помощью метода getDeclaredFields() of Class. Затем вам нужно проверить модификатор каждого поля, чтобы найти частные:

List<Field> privateFields = new ArrayList<>();
Field[] allFields = SomeClass.class.getDeclaredFields();
for (Field field : allFields) {
    if (Modifier.isPrivate(field.getModifiers())) {
        privateFields.add(field);
    }
}

Обратите внимание, что getDeclaredFields() не вернет унаследованные поля.

В конце концов вы получите тип полей с помощью метода Field.getType().

Ответ 2

Вы можете использовать Modifier, чтобы определить, является ли поле закрытым. Не забудьте использовать метод getDeclaredFields, чтобы убедиться, что вы извлекаете частные поля из класса, вызов getFields будет возвращать только общедоступные поля.

public class SomeClass {

    private String aaa;
    private Date date;
    private double ccc;
    public int notPrivate;

    public static void main(String[] args) {
        List<Field> fields = getPrivateFields(SomeClass.class);
        for(Field field: fields){
            System.out.println(field.getName());
        }
    }

    public static List<Field> getPrivateFields(Class<?> theClass){
        List<Field> privateFields = new ArrayList<Field>();

        Field[] fields = theClass.getDeclaredFields();

        for(Field field:fields){
            if(Modifier.isPrivate(field.getModifiers())){
                privateFields.add(field);
            }
        }
        return privateFields;
    }
}

Ответ 3

Вы имеете в виду

Field[] fields = SomeClass.class.getDeclaredFields();

Ответ 4

Попробуйте FieldUtils от apache commons-lang3:

FieldUtils.getAllFieldsList(Class<?> cls)

Ответ 5

Проверьте, является ли поле закрытым

Вы можете фильтровать поля, используя Modifier.isPrivate:

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
// ...
Field field = null;
// retrieve the field in some way
// ...
Modifier.isPrivate(field.getModifiers())

на одном объекте Field, который возвращает true, если поле private


Соберите все поля класса

Чтобы собрать все поля, используйте:

1) Если вам нужны только поля класса без полей, взятых из иерархии классов, вы можете просто использовать:

Field[] fields = SomeClass.class.getDeclaredFields();

2) Если вы не хотите изобретать колесо и получать все поля иерархии классов, вы можете положиться на Apache Commons Lang версия 3.2+, которая обеспечивает FieldUtils.getAllFieldsList:

import java.lang.reflect.Field;
import java.util.AbstractCollection;
import java.util.AbstractList;
import java.util.AbstractSequentialList;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;

import org.apache.commons.lang3.reflect.FieldUtils;
import org.junit.Assert;
import org.junit.Test;

public class FieldUtilsTest {

    @Test
    public void testGetAllFieldsList() {

        // Get all fields in this class and all of its parents
        final List<Field> allFields = FieldUtils.getAllFieldsList(LinkedList.class);

        // Get the fields form each individual class in the type hierarchy
        final List<Field> allFieldsClass = Arrays.asList(LinkedList.class.getFields());
        final List<Field> allFieldsParent = Arrays.asList(AbstractSequentialList.class.getFields());
        final List<Field> allFieldsParentsParent = Arrays.asList(AbstractList.class.getFields());
        final List<Field> allFieldsParentsParentsParent = Arrays.asList(AbstractCollection.class.getFields());

        // Test that `getAllFieldsList` did truly get all of the fields of the the class and all its parents 
        Assert.assertTrue(allFields.containsAll(allFieldsClass));
        Assert.assertTrue(allFields.containsAll(allFieldsParent));
        Assert.assertTrue(allFields.containsAll(allFieldsParentsParent));
        Assert.assertTrue(allFields.containsAll(allFieldsParentsParentsParent));
    }
}

Ответ 6

Использование Java 8:

Field[] fields = String.class.getDeclaredFields();
List<Field> privateFieldList = Arrays.asList(fields).stream().filter(field -> Modifier.isPrivate(field.getModifiers())).collect(
        Collectors.toList());