Abrufen des Werts des öffentlichen statischen endgültigen Felds / der Eigenschaft einer Klasse in Java durch Reflektion

103

Angenommen, ich habe eine Klasse:

public class R {
    public static final int _1st = 0x334455;
}

Wie kann ich den Wert des "_1st" durch Reflexion erhalten?

Viet
quelle
R._1stkonnte nicht arbeiten? Wenn Sie über Android-Entwicklung sprechen, denke ich, dass die RKlasse immer da ist ...
Matthieu
@Matthieu Das dachte ich auch, bis ich heute genau das Gleiche tun musste, aber nur mit der BRKlasse.
Sevastyan Savanyuk

Antworten:

132

Rufen Sie zuerst die Feldeigenschaft der Klasse ab, dann können Sie den Wert abrufen. Wenn Sie den Typ kennen, können Sie eine der get-Methoden mit null verwenden (nur für statische Felder, bei einem statischen Feld wird das an die get-Methode übergebene Argument vollständig ignoriert). Andernfalls können Sie getType verwenden und einen geeigneten Schalter wie folgt schreiben:

Field f = R.class.getField("_1st");
Class<?> t = f.getType();
if(t == int.class){
    System.out.println(f.getInt(null));
}else if(t == double.class){
    System.out.println(f.getDouble(null));
}...
M. Jessup
quelle
Vielen Dank. Ich habe es versucht, aber es hat nicht funktioniert. Bei der Operation f.getInt (null) wird eine Ausnahme ausgelöst. Ich habe es verstanden, aber warum gibt es eine Ausnahme?
Viet
1
Welche Art von Ausnahme haben Sie erhalten?
M. Jessup
Hallo, die Ausnahme e.getMessage () gibt den Feldnamen zurück, der "_1st" ist, und sonst nichts.
Viet
1
Aber was ist die Art der Ausnahme? (dh NullPointerException, SecurityException, ...)
M. Jessup
2
Wie kommt es, dass in der Dokumentation niemals erwähnt wird, dass getInt()das übergebene Argument ignoriert wird? Verbrachte Stunden damit, die Instanz der Klasse dorthin zu bringen.
Sevastyan Savanyuk
70
 R.class.getField("_1st").get(null);

Die Ausnahmebehandlung bleibt dem Leser als Übung überlassen.

Grundsätzlich erhalten Sie das Feld wie jedes andere über Reflektion, aber wenn Sie die get-Methode aufrufen, übergeben Sie eine Null, da es keine Instanz gibt, auf die Sie reagieren können.

Dies funktioniert für alle statischen Felder, unabhängig davon, ob sie endgültig sind. Wenn das Feld nicht öffentlich ist, müssen Sie setAccessible(true)es zuerst aufrufen , und natürlich muss der SecurityManager all dies zulassen.

Yishai
quelle
Ich habe es verstanden. Die Klasse, die ich brauchte, war eigentlich R.id. Danke für Ihre Hilfe!
Viet
1

Ich folgte der gleichen Route (sah durch die generierte R-Klasse) und hatte dann das schreckliche Gefühl, dass es wahrscheinlich eine Funktion in der Resources-Klasse war. Ich lag richtig.

Gefunden dies: Resources :: getIdentifier

Ich dachte, es könnte den Leuten Zeit sparen. Obwohl sie sagen, dass es in den Dokumenten entmutigt ist, ist das nicht allzu überraschend.

Brian
quelle
Sie haben also gefolgert, dass es sich um eine Android-Frage handelt. Sollte in den Tags angegeben worden sein ...
Matthieu
Es ist keine Android-Frage, sondern eine Java-Reflexionsfrage, die ein bestimmtes Beispiel verwendet. Fragen werden basierend auf ihrem Thema markiert.
Matthew Read