Obtener el valor del campo / propiedad final estática pública de una clase en Java a través de la reflexión

103

Digamos que tengo una clase:

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

¿Cómo puedo obtener el valor de "_1st" mediante la reflexión?

Viet
fuente
R._1stno pudo trabajar? Si estás hablando de desarrollo de Android, creo que la Rclase siempre está ahí ...
Matthieu
@Matthieu Yo también lo pensé, hasta el día en que tuve que hacer esto mismo, pero solo con la BRclase.
Sevastyan Savanyuk

Respuestas:

132

Primero recupere la propiedad de campo de la clase, luego puede recuperar el valor. Si conoce el tipo, puede usar uno de los métodos get con nulo (solo para campos estáticos, de hecho, con un campo estático, el argumento pasado al método get se ignora por completo). De lo contrario, puede usar getType y escribir un modificador apropiado como se muestra a continuación:

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
fuente
Gracias. Lo intenté pero no funcionó. Se lanza una excepción a la operación f.getInt (nulo). Lo atrapé, pero ¿cómo es que hay una excepción?
Viet
1
¿Qué tipo de excepción recibió?
M. Jessup
Hola, la excepción e.getMessage () devuelve el nombre del campo, que es "_1st" y nada más.
Viet
1
Pero, ¿cuál es el tipo de excepción? (es decir, NullPointerException, SecurityException, ...)
M. Jessup
2
¿Cómo es que la documentación nunca menciona que getInt()ignora el argumento pasado? Pasé horas intentando que la instancia de la clase pasara allí.
Sevastyan Savanyuk
70
 R.class.getField("_1st").get(null);

El manejo de excepciones se deja como ejercicio para el lector.

Básicamente, obtiene el campo como cualquier otro a través de la reflexión, pero cuando llama al método get, pasa un nulo ya que no hay una instancia sobre la que actuar.

Esto funciona para todos los campos estáticos, independientemente de que sean definitivos. Si el campo no es público, setAccessible(true)primero debe llamarlo y, por supuesto, SecurityManager debe permitir todo esto.

Yishai
fuente
Lo tengo. La clase que necesitaba era R.id. ¡Gracias por tu ayuda!
Viet
1

Estaba siguiendo la misma ruta (mirando a través de la clase R generada) y luego tuve la terrible sensación de que probablemente era una función en la clase Resources. Yo tenía razón.

Encontré esto: Resources :: getIdentifier

Pensé que podría ahorrarle tiempo a la gente. Aunque dicen que está desanimado en los documentos, lo cual no es demasiado sorprendente.

Brian
fuente
Entonces dedujiste que era una pregunta de Android. Debería haber sido indicado en las etiquetas ...
Matthieu
No es una pregunta de Android, es una pregunta de reflexión de Java que usa un ejemplo particular. Las preguntas se etiquetan según su tema.
Matthew Read el