webentwicklung-frage-antwort-db.com.de

Schleife über alle Felder einer Java-Klasse

Ich habe eine Java-Klasse mit einer Anzahl von Fields.

Ich würde gerne alle Felder durchlaufen und etwas für die tun, die null sind. 

Zum Beispiel wenn meine Klasse:

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

An einem anderen Ort würde ich ein ClassWithStuff-Objekt erstellen und ich würde gerne alle Felder in der Klasse durchgehen. Irgendwie so:

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

Gibt es eine Möglichkeit für mich, dies zu erreichen?

18
CodyBugstein

getDeclaredFields für [Klasse] verwenden

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

Ja, mit Nachdenken.

Verwenden Sie das Class-Objekt, um mit der getFields() -Methode auf Field-Objekte zuzugreifen.

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

Dann gehen Sie über die Felder. Dies funktioniert, weil alle Felder, die Sie deklariert haben, public sind. Wenn dies nicht der Fall ist, verwenden Sie getDeclaredFields() , wodurch auf alle Fields zugegriffen wird, die direkt für die Klasse public deklariert sind oder nicht.

6
rgettman

Was gesucht wird, heißt Reflektion . In Reflection können Sie Ihre eigene Klasse oder eine andere Klasse betrachten, um zu sehen, woraus sie besteht. In Java ist Reflection integriert, sodass Sie es sofort verwenden können. Dann kannst du Sachen machen wie - 

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

Sie können dies auch verwenden, um Methoden, Konstruktoren usw. zu erhalten, um ähnliche und coolere Dinge zu tun. 

2
David Grinberg

Eine Java 8+ -Lösung, die die Bibliothek Durian und Stream verwendet.

Die Utility-Methode FieldsAndGetters.fields(Object obj)

Gibt einen Stream aller öffentlichen Felder und ihrer Werte für das angegebene .__ zurück. Objekt.

Dadurch werden die Felder von ClassWithStuff gefunden, da sie alle öffentlich sind.

Mal sehen, wie man es mit (etwas modifiziert) ClassWithStuff benutzt:

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

Beispiel - Name und Wert jedes Felds drucken: 

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

Die Ausgabe:

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

Wie der Ausgang zeigt, werden sogar vererbte öffentliche Felder berücksichtigt.

0
LuCio