30

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?

4

4 回答 4

33

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(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)

于 2013-06-13T19:42:52.820 回答
9

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.

于 2013-06-13T19:43:47.010 回答
3

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.

于 2013-06-13T19:46:38.707 回答
1

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.

于 2018-09-17T13:52:47.397 回答