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

Перебирать все поля класса Java

У меня есть класс Java, который имеет число Fields.

Я хотел бы выполнить Loop над alhehe полями и сделать что-то для нулевого.

Например, если мой класс:

public class ClassWithStuff {
    public int inty;
    public stringy;         
    public Stuff;
    //many more fields
}

В другом месте я бы сделал объект ClassWithStuff, и мне бы хотелось пройти все поля в классе. Вид вроде этого:

for (int i = 0; i < ClassWithStuff.getFields().size(); i++) {
      //do stuff with each one
}

Есть ли способ для достижения этого?

4b9b3361

Ответ 1

Используйте getDeclaredFields в [Class]

ClasWithStuff myStuff = new ClassWithStuff();
Field[] fields = myStuff.getClass().getDeclaredFields();
for(Field f : fields){
   Class t = f.getType();
   Object v = f.get(myStuff);
   if(t == boolean.class && Boolean.FALSE.equals(v)) 
     // found default value
   else if(t.isPrimitive() && ((Number) v).doubleValue() == 0)
     // found default value
   else if(!t.isPrimitive() && v == null)
     // found default value
}

(http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html)

Ответ 2

Да, с отражением.

Используйте объект Class для доступа к объектам Field с помощью метода getFields().

Field[] fields = ClassWithStuff.class.getFields();

Затем сверните по полям. Это работает, потому что все поля, которые вы объявили, public. Если это не так, используйте getDeclaredFields(), который обращается ко всем Fields, которые непосредственно объявлены в классе, public или не.

Ответ 3

То, что ищут, называется отражение. Отражение позволяет вам взглянуть на свой собственный класс или на другой класс, чтобы увидеть, из чего он сделан. У Java есть встроенное отражение, поэтому вы можете использовать его сразу. Затем вы можете делать такие вещи, как -

for(Field f : ClasWithStuff.getFields()){
    System.out.println(f.getName());//or do other stuff with it
}

Вы также можете использовать это, чтобы получать методы, конструкторы и т.д., чтобы делать похожие и более холодные вещи.

Ответ 4

Решение Java 8+ с использованием библиотеки durian и Stream.

FieldsAndGetters.fields(Object obj) метод FieldsAndGetters.fields(Object obj)

Возвращает поток всех открытых полей и их значений для данного объекта.

Это найдет поля ClassWithStuff так как они все общедоступны.

Давайте посмотрим, как использовать его с (немного измененным) ClassWithStuff:

public static class BaseStuff {
    public DayOfWeek dayOfWeek = DayOfWeek.MONDAY;
}

public static class ClassWithStuff extends BaseStuff {
    public int inty = 1;
    public String stringy = "string";
    public Object Stuff = null;
}

Пример - печать имени и значения каждого поля:

public static void main(String[] args) throws Exception {
    ClassWithStuff cws = new ClassWithStuff();
    FieldsAndGetters.fields(cws) 
            .map(field -> field.getKey().getName() + " = " + field.getValue())
            .forEach(System.out::println);
}

Выход:

inty = 1
stringy = string
Stuff = null
dayOfWeek = MONDAY

Как показывает выходной файл, рассматриваются даже унаследованные открытые поля.