web-dev-qa-db-fra.com

Boucle sur tous les champs d'une classe Java

J'ai une classe Java qui a un nombre de Fields.

Je voudrais parcourir tous les champs et faire quelque chose pour ceux qui sont nuls. 

Par exemple si ma classe est:

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

À un autre endroit, je créerais un objet ClassWithStuff et je voudrais parcourir tous les champs de la classe. Un peu comme ça:

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

Y a-t-il un moyen pour moi d'y parvenir?

18
CodyBugstein

Utilisez getDeclaredFields sur [Classe]

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 )

16

Oui, avec réflexion.

Utilisez l'objet Class pour accéder aux objets Field avec la méthode getFields() .

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

Puis boucle sur les champs. Cela fonctionne car tous les champs que vous avez déclarés sont public. Si ce n'est pas le cas, utilisez getDeclaredFields() , qui accède à tous les Fields déclarés directement dans la classe, public ou non.

6
rgettman

Qu'est-ce que vous recherchez s'appelle réflexion . La réflexion vous permet de regarder votre propre classe ou une autre classe pour voir de quoi elle est faite. Java a une réflexion intégrée, vous pouvez donc l'utiliser tout de suite. Ensuite, vous pouvez faire des choses comme - 

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

Vous pouvez également utiliser cela pour obtenir des méthodes, des constructeurs, etc. 

2
David Grinberg

Une solution Java 8+ utilisant la bibliothèque durian et Stream.

La méthode d'utilité FieldsAndGetters.fields(Object obj)

Renvoie un flux de tous les champs publics et leurs valeurs pour le donné objet.

Ceci trouvera les champs de ClassWithStuff puisqu'ils sont tous publics.

Voyons comment l'utiliser avec (légèrement modifié) 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;
}

Exemple - Impression du nom et de la valeur de chaque champ: 

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);
}

Le résultat:

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

Comme le montre le ouptut, même les champs publics hérités sont pris en compte.

0
LuCio