Obtenir la valeur du champ / propriété final statique public d'une classe en Java via la réflexion

103

Dis que j'ai un cours:

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

Comment puis-je obtenir la valeur du "_1st" par réflexion?

Viet
la source
R._1stne pouvait pas fonctionner? Si vous parlez de développement Android, je pense que la Rclasse est toujours là ...
Matthieu
@Matthieu je le pensais aussi, jusqu'à ce jour où je devais faire exactement la même chose, mais uniquement avec la BRclasse.
Sevastyan Savanyuk

Réponses:

132

Récupérez d'abord la propriété field de la classe, puis vous pouvez récupérer la valeur. Si vous connaissez le type, vous pouvez utiliser l'une des méthodes get avec null (pour les champs statiques uniquement, en fait avec un champ statique, l'argument passé à la méthode get est entièrement ignoré). Sinon, vous pouvez utiliser getType et écrire un commutateur approprié comme ci-dessous:

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
la source
Merci. J'ai essayé mais ça n'a pas marché. Une exception est levée à l'opération f.getInt (null). Je l'ai attrapé mais comment se fait-il qu'il y ait une exception?
Viet le
1
Quel genre d'exception avez-vous reçu?
M. Jessup
Salut, l'exception e.getMessage () renvoie le nom du champ, qui est "_1st" et rien d'autre.
Viet le
1
Mais quel est le type de l'exception? (ie NullPointerException, SecurityException, ...)
M. Jessup
2
Comment se fait-il que la documentation ne mentionne jamais qui getInt()ignore l'argument passé? J'ai passé des heures à essayer de faire passer l'instance de la classe.
Sevastyan Savanyuk
70
 R.class.getField("_1st").get(null);

La gestion des exceptions est un exercice pour le lecteur.

Fondamentalement, vous obtenez le champ comme n'importe quel autre via la réflexion, mais lorsque vous appelez la méthode get, vous passez un null car il n'y a aucune instance sur laquelle agir.

Cela fonctionne pour tous les champs statiques, qu'ils soient définitifs. Si le champ n'est pas public, vous devez d'abord l'appeler setAccessible(true), et bien sûr le SecurityManager doit autoriser tout cela.

Yishai
la source
J? ai compris. La classe dont j'avais besoin était en fait R.id. Merci de votre aide!
Viet le
1

Je suivais le même chemin (en regardant à travers la classe R générée) et ensuite j'ai eu ce sentiment terrible que c'était probablement une fonction dans la classe Resources. J'avais raison.

Trouvé ceci: Resources :: getIdentifier

Je pensais que cela pourrait faire gagner du temps aux gens. Bien qu'ils disent que c'est découragé dans la documentation, ce qui n'est pas trop surprenant.

Brian
la source
Vous avez donc déduit que c'était une question Android. Aurait dû être indiqué dans les tags ...
Matthieu
Ce n'est pas une question Android, c'est une question de réflexion Java qui utilise un exemple particulier. Les questions sont étiquetées en fonction de leur sujet.
Matthew a lu