Saya sedikit bingung tentang perbedaan antara getFields
metode dan getDeclaredFields
metode ketika menggunakan refleksi Java.
Saya membaca yang getDeclaredFields
memberi Anda akses ke semua bidang kelas dan yang getFields
hanya mengembalikan bidang publik. Jika ini masalahnya, mengapa Anda tidak selalu menggunakannya getDeclaredFields
?
Dapatkah seseorang tolong uraikan hal ini, dan jelaskan perbedaan antara kedua metode, dan kapan / mengapa Anda ingin menggunakan yang satu di atas yang lain?
java
reflection
BlackHatSamurai
sumber
sumber
getField
bisa mendapatkan bidang yang diwarisi dari superclass tetapigetDeclaredField
tidak bisa.getDeclaredField
batasi sendiri ke kelas tempat Anda memanggil fungsi.getField
tidak dapat mengakses anggota pribadiJawaban:
getFields ()
Semua
public
bidang naik seluruh hirarki kelas.getDeclaredFields ()
Semua bidang, terlepas dari aksesibilitasnya tetapi hanya untuk kelas saat ini, bukan kelas dasar yang berasal dari kelas saat ini.
Untuk mendapatkan semua bidang hierarki, saya telah menulis fungsi berikut:
The
exclusiveParent
kelas disediakan untuk mencegah pengambilan bidang dariObject
. Mungkinnull
jika Anda menginginkanObject
bidang.Untuk memperjelas,
Lists.newArrayList
berasal dari Jambu.Memperbarui
FYI, kode di atas diterbitkan di GitHub dalam proyek LibEx saya di ReflectionUtils .
sumber
Field#get
dan metode serupa. Dengan kata lain, pendekatan ini tidak memungkinkan akses kelas saat ini ke antarmuka pribadi superclass-nya, dengan cara yang sama kompilasi tipikal tidak.setAccessible
dan tidak ada Manajer Keamanan di tempatprivate
bidang hanya dapat diakses melaluigetDeclaredFields
kelas khusus. Setiap bidang (bahkan dengan jenis dan nama yang sama) akan menjadiField
contoh yang berbeda .Seperti yang telah disebutkan,
Class.getDeclaredField(String)
hanya melihat bidang dariClass
mana Anda menyebutnya.Jika Anda ingin mencari
Field
dalamClass
hierarki, Anda dapat menggunakan fungsi sederhana ini:Ini berguna untuk menemukan
private
bidang dari superclass, misalnya. Juga, jika Anda ingin mengubah nilainya, Anda dapat menggunakannya seperti ini:sumber
try try { field = clazz.getDeclaredField(name); } catch (NoSuchFieldException e) { clazz = clazz.getSuperclass(); if(clazz==null){ throw e; } }
public Field[] getFields() throws SecurityException
Mengembalikan array yang berisi objek Field yang mencerminkan semua bidang publik yang dapat diakses dari kelas atau antarmuka yang diwakili oleh objek Class ini. Elemen-elemen dalam array yang dikembalikan tidak diurutkan dan tidak dalam urutan tertentu. Metode ini mengembalikan array dengan panjang 0 jika kelas atau antarmuka tidak memiliki bidang publik yang dapat diakses, atau jika itu mewakili kelas array, tipe primitif, atau batal.
Secara khusus, jika objek Kelas ini mewakili kelas, metode ini mengembalikan bidang publik dari kelas ini dan semua superclassesnya. Jika objek Class ini mewakili antarmuka, metode ini mengembalikan bidang antarmuka ini dan semua antarmuka supernya.
Bidang panjang implisit untuk kelas array tidak tercermin oleh metode ini. Kode pengguna harus menggunakan metode class Array untuk memanipulasi array.
public Field[] getDeclaredFields() throws SecurityException
Mengembalikan array objek Bidang yang mencerminkan semua bidang yang dideklarasikan oleh kelas atau antarmuka yang diwakili oleh objek Kelas ini. Ini termasuk publik, dilindungi, akses default (paket), dan bidang pribadi , tetapi tidak termasuk bidang yang diwarisi . Elemen-elemen dalam array yang dikembalikan tidak diurutkan dan tidak dalam urutan tertentu. Metode ini mengembalikan array dengan panjang 0 jika kelas atau antarmuka menyatakan tidak ada bidang, atau jika objek Kelas ini mewakili tipe primitif, kelas array, atau batal.
Dan bagaimana jika saya membutuhkan semua bidang dari semua kelas induk? Beberapa kode diperlukan, misalnya dari https://stackoverflow.com/a/35103361/755804 :
sumber
Dari tutorial Java Reflection :
sumber