Mendapatkan nilai field / properti public static final dari kelas di Java melalui refleksi

103

Katakanlah saya punya kelas:

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

Bagaimana saya bisa mendapatkan nilai "_1st" melalui refleksi?

Viet
sumber
R._1sttidak bisa bekerja? Jika Anda berbicara tentang pengembangan Android, saya pikir Rkelasnya selalu ada ...
Matthieu
@Matthieu Saya juga berpikir begitu, sampai hari ini ketika saya harus melakukan hal yang sama ini, tetapi hanya dengan BRkelas.
Sevastyan Savanyuk

Jawaban:

132

Pertama-tama ambil properti bidang kelas, lalu Anda dapat mengambil nilainya. Jika Anda mengetahui jenisnya, Anda dapat menggunakan salah satu metode get dengan null (hanya untuk kolom statis, sebenarnya dengan kolom statis argumen yang diteruskan ke metode get diabaikan seluruhnya). Jika tidak, Anda dapat menggunakan getType dan menulis sakelar yang sesuai seperti di bawah ini:

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
sumber
Terima kasih. Saya mencoba tetapi tidak berhasil. Pengecualian dilemparkan pada operasi f.getInt (null). Saya menangkapnya tapi kenapa ada pengecualian?
Viet
1
Jenis pengecualian apa yang Anda terima?
M. Jessup
Hai, Exception e.getMessage () mengembalikan nama bidang, yaitu "_1st" dan tidak ada yang lain.
Viet
1
Tapi apa jenis pengecualiannya? (yaitu NullPointerException, SecurityException, ...)
M. Jessup
2
Kenapa dokumentasi tidak pernah menyebutkan yang getInt()mengabaikan argumen yang disampaikan? Menghabiskan waktu berjam-jam untuk mencoba membuat instance kelas lulus di sana.
Sevastyan Savanyuk
70
 R.class.getField("_1st").get(null);

Penanganan pengecualian dibiarkan sebagai latihan bagi pembaca.

Pada dasarnya Anda mendapatkan bidang seperti yang lain melalui refleksi, tetapi ketika Anda memanggil metode get, Anda mengirimkan null karena tidak ada contoh untuk ditindaklanjuti.

Ini berfungsi untuk semua bidang statis, terlepas dari finalnya. Jika kolomnya bukan untuk publik, Anda perlu memanggilnya setAccessible(true)terlebih dahulu, dan tentu saja SecurityManager harus mengizinkan semua ini.

Yishai
sumber
Saya mendapatkannya. Kelas yang saya butuhkan sebenarnya adalah R.id. Terima kasih atas bantuan Anda!
Viet
1

Saya mengikuti rute yang sama (melihat melalui kelas R yang dihasilkan) dan kemudian saya memiliki perasaan buruk ini mungkin fungsi di kelas Sumber Daya. Saya benar.

Ketemu ini: Resources :: getIdentifier

Pikir itu mungkin menghemat waktu orang. Meskipun mereka mengatakan itu berkecil hati di dokumen, itu tidak terlalu mengejutkan.

Brian
sumber
Jadi Anda menyimpulkan itu adalah pertanyaan Android. Seharusnya telah diindikasikan dalam tag ...
Matthieu
Ini bukan pertanyaan Android, ini pertanyaan refleksi Java yang menggunakan contoh tertentu. Pertanyaan diberi tag berdasarkan topiknya.
Matius Membaca