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?
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 )
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.
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.
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.