I have a Java class that has a number of Fields
.
I would like to Loop over al lthe fields and do something for the one's that are null.
For example if my class is:
public class ClassWithStuff {
public int inty;
public stringy;
public Stuff;
//many more fields
}
In another location, I'd make a ClassWithStuff
object and I would like to go though all the fields in the class. Kind of like this:
for (int i = 0; i < ClassWithStuff.getFields().size(); i++) {
//do stuff with each one
}
Is there any way for me to achieve this?
Use getDeclaredFields
on [Class]
ClasWithStuff myStuff = new ClassWithStuff();
Field[] fields = myStuff.getClass().getDeclaredFields();
for(Field f : fields){
Class t = f.getType();
Object v = f.get(o);
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)
Yes, with reflection.
Use the Class
object to access Field
objects with the getFields()
method.
Field[] fields = ClassWithStuff.class.getFields();
Then loop over the fields. This works because all fields you have declared are public
. If they aren't, then use getDeclaredFields()
, which accesses all Fields
that are directly declared on the class, public
or not.
What are looking for is called reflection. Reflection lets you look at your own class, or another class to see what it is made of. Java has reflection built in, so you can use it right away. Then you can do stuff like -
for(Field f : ClasWithStuff.getFields()){
System.out.println(f.getName());//or do other stuff with it
}
You can also use this to get methods, constructors, etc, to do similar and cooler stuff.
A Java 8+ solution using the library durian and Stream
.
The utility method FieldsAndGetters.fields(Object obj)
Returns a Stream of all public fields and their values for the given
object.
This will find the fields of ClassWithStuff
since they all are public.
Let's see how to use it with (a little bit modified) 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;
}
Example - Printing the name and value of each field:
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);
}
The output:
inty = 1
stringy = string
Stuff = null
dayOfWeek = MONDAY
As the ouptut shows even inherited public fields are considered.