Ottenere il valore del campo / proprietà finale statico pubblico di una classe in Java tramite la riflessione


103

Di 'che ho un corso:

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

Come posso ottenere il valore di "_1st" tramite riflessione?


R._1stnon potrebbe funzionare? Se stai parlando di sviluppo Android, penso che la Rclasse sia sempre lì ...
Matthieu

@ Matthieu lo pensavo anch'io, fino ad oggi, quando ho dovuto fare la stessa cosa, ma solo con la BRclasse.
Sevastyan Savanyuk

Risposte:


132

Recupera prima la proprietà del campo della classe, quindi puoi recuperare il valore. Se conosci il tipo puoi usare uno dei metodi get con null (solo per i campi statici, infatti con un campo statico l'argomento passato al metodo get viene ignorato del tutto). Altrimenti puoi usare getType e scrivere un interruttore appropriato come di seguito:

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));
}...

Grazie. Ho provato ma non ha funzionato. Viene generata un'eccezione durante l'operazione f.getInt (null). L'ho preso ma come mai c'è un'eccezione?
Viet

1
Che tipo di eccezione hai ricevuto?
M. Jessup

Salve, l'eccezione e.getMessage () restituisce il nome del campo, che è "_1st" e nient'altro.
Viet

1
Ma qual è il tipo di eccezione? (ovvero NullPointerException, SecurityException, ...)
M. Jessup,

2
Come mai la documentazione non menziona mai che getInt()ignora l'argomento passato? Ho passato ore a cercare di far passare l'istanza della classe.
Sevastyan Savanyuk

70
 R.class.getField("_1st").get(null);

La gestione delle eccezioni è lasciata come esercizio per il lettore.

Fondamentalmente ottieni il campo come qualsiasi altro tramite riflessione, ma quando chiami il metodo get passi un valore nullo poiché non c'è alcuna istanza su cui agire.

Funziona per tutti i campi statici, indipendentemente dal fatto che siano definitivi. Se il campo non è pubblico, è necessario setAccessible(true)prima chiamarlo e, naturalmente, SecurityManager deve consentire tutto ciò.


Capito. La classe di cui avevo bisogno era in realtà R.id. Grazie per l'aiuto!
Viet

1

Stavo seguendo lo stesso percorso (guardando attraverso la classe R generata) e poi ho avuto questa terribile sensazione che probabilmente fosse una funzione nella classe Resources. Avevo ragione.

Trovato questo: Resources :: getIdentifier

Ho pensato che avrebbe potuto far risparmiare tempo alle persone. Anche se dicono che è scoraggiato nei documenti, il che non è troppo sorprendente.


Quindi hai dedotto che fosse una domanda su Android. Avrebbe dovuto essere indicato nei tag ...
Matthieu

Non è una domanda su Android, è una domanda di riflessione su Java che utilizza un esempio particolare. Le domande vengono contrassegnate in base al loro argomento.
Matthew Read
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.