IllegalArgumentException, wenn die Einstellung public-member
Ich habe das Spiel mit reflection in Java... und ich bin ein bisschen ratlos.
Ich hoffe, dass das folgende Programm würde mir erlauben, um den Wert zu ändern, der eine öffentliche member-variable innerhalb einer Klasse. Allerdings bekomme ich eine IllegalArgumentException. Irgendwelche Ideen?
public class ColinTest {
public String msg = "fail";
public ColinTest() { }
public static void main(String args[]) throws Exception {
ColinTest test = new ColinTest();
Class c = test.getClass();
Field[] decfields = c.getDeclaredFields();
decfields[0].set("msg", "success");
System.out.println(ColinTest.msg)
}
}
Erhalte ich diese Meldung -
Exception in thread "main" java.lang.IllegalArgumentException
at sun.reflect.UnsafeFieldAccessorImpl.ensureObj(UnsafeFieldAccessorImpl.java:37)
at sun.reflect.UnsafeObjectFieldAccessorImpl.set(UnsafeObjectFieldAccessorImpl.java:57)
at java.lang.reflect.Field.set(Field.java:656)
at ColinTest.main(ColinTest.java:44)
Dank.
InformationsquelleAutor colinjwebb | 2009-05-28
Du musst angemeldet sein, um einen Kommentar abzugeben.
Das erste argument der
- Feld.set
Methode sollte das Objekt, das Sie reflektieren.Lesen sollte:
Darüber hinaus die endgültige
System.out.println
rufen, sollten sich auf dertest
- Objekt, anstatt die KlasseColinTest
, wie ich vermute, die Absicht ist, um die Ausgabe der Inhalte dertest.msg
Feld.Update
Wie bereits von toolkit und Chris, die
- Klasse.getDeclaredField
Methode kann verwendet werden, um geben Sie den Namen des Feldes, um es abzurufen:Dann, die
set
Methode dermsgField
kann aufgerufen werden als:Dieser Weg hat seinen nutzen, wie bereits betont, toolkit, wenn es mehr Felder, die dem Objekt Hinzugefügt, die Reihenfolge der Felder, die zurückgegeben werden, von
Class.getDeclaredFields
nicht unbedingt Rückkehr das Feldmsg
als das erste element des Arrays. Abhängig von der Reihenfolge der zurückgegebenen array um eine bestimmte Weise, kann zu Problemen führen, wenn änderungen vorgenommen werden, um die Klasse.Daher wäre es wahrscheinlich eine bessere Idee zu verwenden
getDeclaredField
und erklären Sie den Namen des gewünschten Feldes.decFields[0]
wenn Sie planen, fügen Sie weitere Felder in der Zukunft!InformationsquelleAutor coobird
Den ersten arg zu set() sollte das Objekt, dessen Feld Sie ändern... und zwar test.
InformationsquelleAutor CurtainDog
Bitte stellen Sie sicher, dass der code, den Sie post, die wirklich kompiliert (Sie möchten
test.msg
, nichtColinTest.msg
).Können Sie auch erwägen, eine neuere version von Java, die eine spezifischere Fehlermeldung:
die wahrscheinlich führten Sie zu der Lösung, die andere geschrieben haben.
InformationsquelleAutor Nicholas Riley
Wenn Sie anrufen
getDeclaredFields
, wobei jedes array-element enthält eineField
- Objekt repräsentiert ein Feld in der Klasse, nicht auf eine instantiierte Objekt.Deshalb müssen Sie das Objekt angeben, auf dem Sie möchten, legen Sie dieses Feld, wenn mit dem setter:
Danke, sah ich, dass auch direkt nach der Buchung, so ich befestigt es in einem edit sofort 😉
InformationsquelleAutor Christian Hang-Hicks
Was Sie wollen, ist:
Aufpassen mit
decfields[0]
da bekommen Sie vielleicht nicht das bekommen, was Sie erwartet, wenn Sie fügen Sie ein zweites Feld Ihre Klasse (Sie sind nicht zu prüfen, dassdecfields[0]
entspricht dermsg
Feld)InformationsquelleAutor toolkit
Stolperte ich accros dieser Seite, weil komischerweise, kann ich keine sets public string Feld in meiner Klasse. Der code wird eine neue Zeile in einer ArrayList in jeder for-Schleife. Das problem ist, ich lege Instanziierung code des neuen Objekts (mit Reflexion) nur einmal, außerhalb des inneren für.
Überprüfen, dass ich jetzt verschieben Sie die Klasse.forName(fqnModel) außerhalb der while-Schleife. Da sicherlich brauchen wir nur zum erstellen von Klassen-Objekt nur einmal. Aber dann, vor jedem for-Schleife erstelle ich ein model-Objekt, schließlich werden in einer ArrayList.
Klar zu sein, das ist mein BiroModel Klasse Aussehen:
}
Ich eine Konvention ist hier, dass alle Feld-Objekt sollte als public deklariert. Aber, da muss ich EL-syntax, die ich noch brauchen, um zu erstellen, getter/setter für diesen öffentlichen Bereich.
InformationsquelleAutor swdev