Java: pobierz wszystkie nazwy zmiennych w klasie


Odpowiedzi:


135
Field[] fields = YourClassName.class.getFields();

zwraca tablicę wszystkich publicznych zmiennych klasy.

getFields()zwróć pola w całej dziedziczeniu klasowym. Jeśli chcesz, aby pola były zdefiniowane tylko w danej klasie, a nie w jej nadklasach, użyj getDeclaredFields()i filtruj pola public, stosując następujące Modifierpodejście:

Modifier.isPublic(field.getModifiers());

YourClassName.classDosłowne faktycznie reprezentuje obiekt typu java.lang.Class. Sprawdź jego dokumentację, aby znaleźć bardziej interesujące metody refleksji.

Powyższa Fieldklasa to java.lang.reflect.Field. Możesz rzucić okiem na cały java.lang.reflectpakiet.


2
uwaga - początkowo moja odpowiedź zawierała błędne stwierdzenie, ale została kilkakrotnie przegłosowana. Przeczytaj uważniej;)
Bozho

1
@downvoter - błąd był wcześniej. Jeśli teraz widzisz, udostępnij.
Bozho

czy to rozwiązanie jest powolne? czy możemy z niego swobodnie korzystać?
Dany Y

w porządku. Ale nie nadużywaj tego.
Bozho


15

Możesz użyć dowolnego z dwóch w zależności od potrzeb:

Field[] fields = ClassName.class.getFields(); // returns inherited members but not private members.
Field[] fields = ClassName.class.getDeclaredFields(); // returns all members including private members but not inherited members.

Aby odfiltrować tylko pola publiczne z powyższej listy (na podstawie wymagań) użyj poniższego kodu:

List<Field> fieldList = Arrays.asList(fields).stream().filter(field -> Modifier.isPublic(field.getModifiers())).collect(
    Collectors.toList());

2

Jak wspomniało kilku użytkowników, poniższy kod może pomóc znaleźć wszystkie pola w danej klasie.

TestClass testObject= new TestClass().getClass();
Method[] methods = testObject.getMethods();
for (Method method:methods)
{
    String name=method.getName();
    if(name.startsWith("get"))
    {
        System.out.println(name.substring(3));
    }else if(name.startsWith("is"))
    {
        System.out.println(name.substring(2));
    }
}

Jednak bardziej interesujące podejście jest poniżej:

Z pomocą biblioteki Jacksona udało mi się znaleźć wszystkie właściwości klas typu String / integer / double i odpowiednie wartości w klasie Map. ( bez używania interfejsu API odbić! )

TestClass testObject = new TestClass();
com.fasterxml.jackson.databind.ObjectMapper m = new com.fasterxml.jackson.databind.ObjectMapper();

Map<String,Object> props = m.convertValue(testObject, Map.class);

for(Map.Entry<String, Object> entry : props.entrySet()){
    if(entry.getValue() instanceof String || entry.getValue() instanceof Integer || entry.getValue() instanceof Double){
        System.out.println(entry.getKey() + "-->" + entry.getValue());
    }
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.