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?


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

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.


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.


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
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.