Перебирать все поля класса 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
}
Есть ли способ для достижения этого?
Ответы
Ответ 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
Как показывает выходной файл, рассматриваются даже унаследованные открытые поля.