2009-04-06 17 views
3

Ich habe eine Klasse mit zahlreichen Parametern verschiedener Typen. Ich möchte alle Typ-A-Mitglieder iterieren, und führen Sie eine spezifische Funktionen (A.doSomething())Verwenden Sie Reflektion zum Iterieren über Klassenmitglieder

Diese kompilieren nicht einmal: Die Umwandlung von Feld zu XPathDataElement ist illegal

Field[] fields = this.getClass().getDeclaredFields(); 
    for (Field field : fields) { 
    if (field. getType().getName().equals(XPathDataElement.class.getName())) 
     {    
       tmp = (XPathDataElement)field; // Doesn't compile 
       sb.append(field.getName() + ":"); 
       tmp.update(); 
     } 
    } 

Dank!

+0

Sie müssen oben mehr Einzelheiten über das, was Sie wollen und warum .. Der Beispielcode und die Beschreibung sind nicht klar genug. – TofuBeer

Antwort

10

Es ist schwer, den Code zu debuggen, wenn Sie nicht sagen, was mit ihm los ist.

Zwei Dinge, die ich sehen kann:

  1. Es gibt keine Notwendigkeit Strings zu vergleichen, wenn der Typ des Feldes die richtige Klasse ist, zu entscheiden.

    if (field.getType().equals(XPathDataElement.class)) 
    

    sollte funktionieren.

    Edit: Steve Reed points out, dass man es nicht unbedingt sein müssen, genau XPathDataElement; Eine Unterklasse wird genauso gut funktionieren. Um zu überprüfen, ob das Feld als XPathDataElement behandelt werden kann, sollten Sie Class.isAssignableFrom(Class) verwenden.

    if (XPathDataElement.class.isAssignableFrom(field.getType())) 
    

    wäre der Code.

  2. Ich denke, Ihre wahre Frage ist, wie man den Wert eines Feldes nachdenklich bekommt? Wenn ja, dann ist Field.get(Object) was du willst. Das Objekt, das Sie an get() übergeben, ist das Objekt, dessen Feld Sie abrufen möchten. wenn Sie auf this (das ist ein stark Code Geruch) betrieben wird, dann würde Ihr Code

    XPathDataElement tmp = (XPathDataElement) field.get(this); 
    
+0

Sie haben absolut Recht mit Ihrem ersten Kommentar, ich habe den Beitrag bearbeitet. Vielen Dank! – Yossale

0

Sie scheinen der obj, die Sie in XPathDataElement in der Schleife umgewandelt haben, nichts zuzuordnen.

Sie wollen wahrscheinlich etwas tun:

tmp = (XPathDataElement)field.get(this); 
2

ich stark Reflexion vorschlagen zu vermeiden, wenn Sie es wirklich brauchen.

Schreiben Sie einfach den Code aus:

this.x.doSomething(); 
this.y.doSomething(); 
this.z.doSomething(); 

Oder wenn Sie mögen:

for (A a : new A[] { 
    this.x, this.y, this.z 
}) { 
    a.doSomething(); 
} 
+1

Würdest du gerne näher erläutern, warum ich Reflektion nicht benutzen sollte? Vielen Dank! – Yossale

+0

Sie verlieren kompilieren Zeit Sicherheit, wird es ein bisschen langsamer, in der Regel sollten Sie Schnittstellen über Reflexion verwenden, um sicherzustellen, dass die Dinge da sind. Kompilierzeit Sicherheit ist einer der großen Pluspunkte in Java (für einige ist es auch einer der Nachteile). Können Sie näher erläutern, warum Sie die Reflexion verwenden möchten? – TofuBeer

+0

Was TofuBear sagte, plus: Es ist mehr Code und Code, der leichter zu fälschen und schwer zu folgen ist. Reflektion und (Mobile Code) Sicherheit vermischen sich auch nicht sehr gut. –

1

Ein paar Hinweise sein:

  1. Vergleichen Sie die Klassen für die Gleichstellung , nicht ihre Namen.

    feld.getType(). Gleich (XPathDataElement.Klasse)

  2. Oder noch besser, verwenden isAssignableFrom(java.lang.Class) den Fall zu behandeln, in denen die Klasse einen Rückgabetyp als sublclass von dem, was für

    XPathDataElement.class.isAssignableFrom (field.getType()) Sie suchen erklärt

  3. Sie iterieren Felder, nicht Methode. Ihre Frage führt mich Sie letztere wollen annehmen, und wenn ja, benutzen.

    this.getClass() getDeclaredMethods()