Apa itu refleksi, dan mengapa itu berguna?
Saya khususnya tertarik pada Java, tetapi saya berasumsi prinsipnya sama dalam bahasa apa pun.
java
reflection
terminology
Lehane
sumber
sumber
@Jailbreak
. Ini memberikan akses langsung, tipe-aman ke bidang pribadi, metode, dll. Biarkan kompiler Java dengan aman memverifikasi kode Anda dan biarkan Manifold menghasilkan akses refleksi yang mendasari untuk Anda. Pelajari lebih lanjut: manifold.systems/docs.html#type-safe-reflectionJawaban:
Refleksi nama digunakan untuk menggambarkan kode yang dapat memeriksa kode lain dalam sistem yang sama (atau dirinya sendiri).
Misalnya, Anda memiliki objek dengan tipe yang tidak dikenal di Java, dan Anda ingin memanggil metode 'doSomething' jika ada. Sistem pengetikan statis Java tidak benar-benar dirancang untuk mendukung ini kecuali objeknya sesuai dengan antarmuka yang dikenal, tetapi menggunakan refleksi, kode Anda dapat melihat objek dan mencari tahu apakah ia memiliki metode yang disebut 'doSomething' dan kemudian memanggilnya jika Anda ingin.
Jadi, untuk memberi Anda contoh kode ini di Jawa (bayangkan objek yang dimaksud adalah foo):
Satu kasus penggunaan yang sangat umum di Jawa adalah penggunaan dengan anotasi. JUnit 4, misalnya, akan menggunakan refleksi untuk melihat kelas Anda untuk metode yang ditandai dengan penjelasan @Test, dan kemudian akan memanggil mereka ketika menjalankan unit test.
Ada beberapa contoh refleksi yang baik untuk memulai di http://docs.oracle.com/javase/tutorial/reflect/index.html
Dan akhirnya, ya, konsepnya cukup mirip dengan bahasa yang diketik secara statis lainnya yang mendukung refleksi (seperti C #). Dalam bahasa yang diketik secara dinamis, use case yang dijelaskan di atas kurang perlu (karena kompiler akan memungkinkan metode apa pun dipanggil pada objek apa pun, gagal saat runtime jika tidak ada), tetapi kasus kedua mencari metode yang ditandai atau bekerja dengan cara tertentu masih umum.
Perbarui dari komentar:
sumber
Method
,Constructor
,Modifier
,Field
,Member
, pada dasarnya tampaknya semua kecualiClass
) berada dalamjava.lang.*reflect*
paket. Mungkin konsep "refleksi" secara komprehensif mencakup "tipe introspeksi" dan modifikasi pada saat run-time?Misalnya, semua objek di Jawa memiliki metode
getClass()
, yang memungkinkan Anda menentukan kelas objek bahkan jika Anda tidak mengetahuinya pada waktu kompilasi (misalnya jika Anda menyatakannya sebagaiObject
) - ini mungkin tampak sepele, tetapi refleksi seperti itu tidak mungkin dalam bahasa yang kurang dinamis sepertiC++
. Penggunaan yang lebih maju memungkinkan Anda membuat daftar dan memanggil metode, konstruktor, dll.Refleksi penting karena memungkinkan Anda menulis program yang tidak harus "mengetahui" semuanya pada waktu kompilasi, membuatnya lebih dinamis, karena mereka dapat diikat bersama saat runtime. Kode dapat ditulis terhadap antarmuka yang dikenal, tetapi kelas aktual yang akan digunakan dapat dipakai menggunakan refleksi dari file konfigurasi.
Banyak kerangka kerja modern menggunakan refleksi secara luas karena alasan ini. Sebagian besar bahasa modern lainnya menggunakan refleksi juga, dan dalam bahasa scripting (seperti Python) mereka bahkan lebih terintegrasi, karena terasa lebih alami dalam model pemrograman umum bahasa-bahasa tersebut.
sumber
C++
memang memiliki informasi jenis Run-time. RTTISalah satu kegunaan refleksi favorit saya adalah metode dump Java di bawah ini. Dibutuhkan objek apa pun sebagai parameter dan menggunakan API refleksi Java untuk mencetak setiap nama bidang dan nilai.
sumber
callCount
harus disetel ke nol. Nilainya digunakan untuk menentukan berapa banyak tab yang harus mendahului setiap baris output: setiap kali dump perlu membuang "subobject", output akan dicetak sebagai bersarang di induknya. Metode itu terbukti berguna ketika dibungkus dengan yang lain. PertimbangkanprintDump(Object obj){ System.out.println(dump(obj, 0)); }
.Penggunaan Refleksi
Refleksi umumnya digunakan oleh program yang membutuhkan kemampuan untuk memeriksa atau memodifikasi perilaku runtime aplikasi yang berjalan di mesin virtual Java. Ini adalah fitur yang relatif canggih dan harus digunakan hanya oleh pengembang yang memiliki pemahaman yang kuat tentang dasar-dasar bahasa. Dengan peringatan itu dalam pikiran, refleksi adalah teknik yang kuat dan dapat memungkinkan aplikasi untuk melakukan operasi yang seharusnya tidak mungkin dilakukan.
Fitur Ekstensibilitas
Aplikasi dapat menggunakan kelas eksternal yang ditentukan pengguna dengan membuat instance objek yang dapat diperluas menggunakan nama yang sepenuhnya memenuhi syarat. Browser Kelas dan Lingkungan Pengembangan Visual Browser kelas harus dapat menyebutkan anggota kelas. Lingkungan pengembangan visual dapat mengambil manfaat dari penggunaan informasi jenis yang tersedia dalam refleksi untuk membantu pengembang dalam menulis kode yang benar. Debugger dan Alat Uji Debugger harus dapat memeriksa anggota pribadi di kelas. Rangkaian uji dapat menggunakan refleksi untuk secara sistematis memanggil set API yang dapat ditemukan yang ditentukan pada kelas, untuk memastikan tingkat tinggi cakupan kode dalam rangkaian uji.
Kerugian Refleksi
Refleksi itu kuat, tetapi tidak boleh digunakan tanpa pandang bulu. Jika dimungkinkan untuk melakukan operasi tanpa menggunakan refleksi, maka lebih baik untuk menghindari menggunakannya. Perhatian berikut harus diingat ketika mengakses kode melalui refleksi.
Karena refleksi melibatkan jenis yang diselesaikan secara dinamis, optimasi mesin virtual Java tertentu tidak dapat dilakukan. Akibatnya, operasi reflektif memiliki kinerja lebih lambat daripada rekan non-reflektif mereka dan harus dihindari di bagian kode yang sering disebut dalam aplikasi yang sensitif terhadap kinerja.
Refleksi memerlukan izin runtime yang mungkin tidak ada saat berjalan di bawah manajer keamanan. Ini merupakan pertimbangan penting untuk kode yang harus dijalankan dalam konteks keamanan terbatas, seperti dalam Applet.
Karena refleksi memungkinkan kode untuk melakukan operasi yang ilegal dalam kode non-reflektif, seperti mengakses bidang dan metode pribadi, penggunaan refleksi dapat mengakibatkan efek samping yang tidak terduga, yang dapat membuat kode menjadi tidak berfungsi dan dapat merusak portabilitas. Kode reflektif memecah abstraksi dan karenanya dapat mengubah perilaku dengan peningkatan platform.
sumber: API Refleksi
sumber
Refleksi adalah mekanisme kunci untuk memungkinkan aplikasi atau kerangka kerja untuk bekerja dengan kode yang mungkin belum ditulis!
Ambil contoh file web.xml khas Anda. Ini akan berisi daftar elemen servlet, yang berisi elemen kelas servlet bersarang. Wadah servlet akan memproses file web.xml, dan membuat contoh baru baru dari setiap kelas servlet melalui refleksi.
Contoh lain adalah Java API untuk XML Parsing (JAXP) . Di mana penyedia parser XML 'terhubung' melalui properti sistem terkenal, yang digunakan untuk membuat instance baru melalui refleksi.
Dan akhirnya, contoh paling komprehensif adalah Spring yang menggunakan refleksi untuk membuat biji-bijiannya, dan untuk penggunaan proksi yang berat
sumber
Tidak setiap bahasa mendukung refleksi tetapi prinsip-prinsipnya biasanya sama dalam bahasa yang mendukungnya.
Refleksi adalah kemampuan untuk "merefleksikan" pada struktur program Anda. Atau lebih konkret. Untuk melihat objek dan kelas yang Anda miliki dan secara terprogram mendapatkan kembali informasi tentang metode, bidang, dan antarmuka yang mereka implementasikan. Anda juga dapat melihat hal-hal seperti anotasi.
Ini berguna dalam banyak situasi. Di mana pun Anda ingin dapat secara dinamis memasukkan kelas ke dalam kode Anda. Banyak pembuat pemetaan relasional objek menggunakan refleksi untuk dapat membuat instance objek dari database tanpa mengetahui terlebih dahulu objek apa yang akan mereka gunakan. Arsitektur plug-in adalah tempat lain di mana refleksi berguna. Mampu memuat kode secara dinamis dan menentukan apakah ada jenis di sana yang mengimplementasikan antarmuka yang tepat untuk digunakan sebagai plugin adalah penting dalam situasi tersebut.
sumber
Refleksi memungkinkan instantiasi objek baru, doa metode, dan mendapatkan / set operasi pada variabel kelas secara dinamis pada saat run time tanpa memiliki pengetahuan sebelumnya tentang implementasinya.
Dalam contoh di atas parameter nol adalah objek yang ingin Anda panggil metode ini. Jika metode ini statis, Anda memberikan nol. Jika metode ini tidak statis, maka sambil memohon Anda harus memberikan contoh MyObject yang valid, bukan nol
Refleksi juga memungkinkan Anda untuk mengakses anggota pribadi / metode kelas:
.
java.lang.reflect
). Metadata kelas dapat diakses melaluijava.lang.Class
.Refleksi adalah API yang sangat kuat tetapi dapat memperlambat aplikasi jika digunakan secara berlebihan, karena ia menyelesaikan semua jenis saat runtime.
sumber
Java Reflection cukup kuat dan bisa sangat berguna. Java Reflection memungkinkan untuk memeriksa kelas, antarmuka, bidang dan metode saat runtime, tanpa mengetahui nama-nama kelas, metode, dll. Pada waktu kompilasi. Dimungkinkan juga untuk instantiate objek baru, memanggil metode dan mendapatkan / set nilai bidang menggunakan refleksi.
Contoh Java Reflection yang cepat untuk menunjukkan kepada Anda seperti apa bentuk refleksi itu:
Contoh ini memperoleh objek Kelas dari kelas yang disebut MyObject. Menggunakan objek kelas contoh mendapat daftar metode di kelas itu, iterates metode dan cetak nama mereka.
Bagaimana cara kerjanya dijelaskan di sini
Sunting : Setelah hampir 1 tahun saya mengedit jawaban ini karena ketika membaca tentang refleksi saya mendapat beberapa kegunaan Refleksi lagi.
Ketika konteks Spring memproses elemen <bean> ini, ia akan menggunakan Class.forName (String) dengan argumen "com.example.Foo" untuk membuat instance Kelas itu.
Kemudian akan menggunakan refleksi lagi untuk mendapatkan setter yang sesuai untuk elemen <properti> dan mengatur nilainya ke nilai yang ditentukan.
Untuk metode pribadi,
Untuk bidang pribadi,
sumber
Contoh:
Ambil contoh aplikasi jarak jauh yang memberi aplikasi Anda objek yang Anda peroleh menggunakan Metode API mereka. Sekarang berdasarkan pada objek Anda mungkin perlu melakukan semacam perhitungan.
Penyedia menjamin bahwa objek dapat dari 3 jenis dan kita perlu melakukan perhitungan berdasarkan pada jenis objek apa.
Jadi kita dapat menerapkan dalam 3 kelas masing-masing berisi logika yang berbeda. Jelas informasi objek tersedia dalam runtime sehingga Anda tidak dapat secara statis kode untuk melakukan perhitungan maka refleksi digunakan untuk instantiate objek kelas yang Anda perlukan untuk melakukan perhitungan berdasarkan pada objek yang diterima dari penyedia.
sumber
instanceof
untuk menentukan tipe objek saat runtime?Contoh sederhana untuk refleksi. Dalam permainan catur, Anda tidak tahu apa yang akan dipindahkan oleh pengguna pada saat run time. refleksi dapat digunakan untuk memanggil metode yang sudah diterapkan pada saat run time:
sumber
Refleksi adalah API yang digunakan untuk memeriksa atau memodifikasi perilaku metode, kelas, antarmuka saat runtime.
java.lang.reflect package
.Paket
java.lang
danjava.lang.reflect
menyediakan kelas untuk refleksi java.Refleksi dapat digunakan untuk mendapatkan informasi tentang -
Kelas The
getClass()
metode yang digunakan untuk mendapatkan nama dari kelas yang objek milik.Konstruktor The
getConstructors()
metode yang digunakan untuk mendapatkan konstruktor publik dari kelas mana objek milik.Metode tersebut
getMethods()
metode yang digunakan untuk mendapatkan metode umum dari kelas mana suatu benda milik.The API Refleksi terutama digunakan dalam:
IDE (Lingkungan Pengembangan Terpadu) misalnya Eclipse, MyEclipse, NetBeans dll.
Debugger dan Alat Uji dll.
Keuntungan Menggunakan Refleksi:
Fitur Ekstensibilitas: Aplikasi dapat menggunakan kelas eksternal yang ditentukan pengguna dengan membuat turunan objek ekstensi menggunakan nama mereka yang sepenuhnya memenuhi syarat.
Alat debugging dan pengujian: Debugger menggunakan properti refleksi untuk memeriksa anggota pribadi di kelas.
Kekurangan:
Overhead Kinerja: Operasi reflektif memiliki kinerja lebih lambat daripada rekan non-reflektifnya, dan harus dihindari di bagian kode yang sering disebut dalam aplikasi yang sensitif terhadap kinerja.
Paparan Internal: Kode reflektif memecah abstraksi dan karena itu dapat mengubah perilaku dengan peningkatan platform.
Ref: Java Reflection javarevisited.blogspot.in
sumber
Sesuai pemahaman saya:
Refleksi memungkinkan pemrogram untuk mengakses entitas dalam program secara dinamis. yaitu ketika sedang mengkode aplikasi jika programmer tidak mengetahui tentang suatu kelas atau metodenya, ia dapat menggunakan kelas tersebut secara dinamis (pada saat run time) dengan menggunakan refleksi.
Ini sering digunakan dalam skenario di mana nama kelas sering berubah. Jika situasi seperti itu muncul, maka rumit bagi programmer untuk menulis ulang aplikasi dan mengubah nama kelas berulang kali.
Sebaliknya, dengan menggunakan refleksi, perlu khawatir tentang kemungkinan perubahan nama kelas.
sumber
Refleksi adalah serangkaian fungsi yang memungkinkan Anda untuk mengakses informasi runtime dari program Anda dan memodifikasinya perilaku (dengan beberapa batasan).
Ini berguna karena memungkinkan Anda untuk mengubah perilaku runtime tergantung pada informasi meta program Anda, yaitu, Anda dapat memeriksa jenis pengembalian fungsi dan mengubah cara Anda menangani situasi.
Dalam C # misalnya Anda dapat memuat perakitan (.dll) dalam runtime memeriksanya, menavigasi kelas dan mengambil tindakan sesuai dengan apa yang Anda temukan. Itu juga memungkinkan Anda membuat turunan kelas saat runtime, menjalankan metode, dll.
Di mana itu bisa berguna? Tidak berguna setiap saat tetapi untuk situasi konkret. Misalnya, Anda dapat menggunakannya untuk mendapatkan nama kelas untuk tujuan logging, untuk secara dinamis membuat handler untuk acara sesuai dengan apa yang ditentukan pada file konfigurasi dan seterusnya ...
sumber
Saya hanya ingin menambahkan beberapa poin ke semua yang terdaftar.
Dengan API Refleksi Anda dapat menulis
toString()
metode universal untuk objek apa pun.Ini berguna saat debugging.
Berikut ini beberapa contohnya:
sumber
Refleksi adalah membiarkan objek melihat penampilan mereka. Argumen ini sepertinya tidak ada hubungannya dengan refleksi. Sebenarnya, ini adalah kemampuan "mengidentifikasi diri".
Refleksi itu sendiri adalah kata untuk bahasa-bahasa seperti itu yang tidak memiliki kemampuan pengetahuan-diri dan penginderaan-diri seperti Java dan C #. Karena mereka tidak memiliki kemampuan pengetahuan-diri, ketika kita ingin mengamati bagaimana kelihatannya, kita harus memiliki hal lain untuk merenungkan bagaimana itu terlihat. Bahasa dinamis yang sangat baik seperti Ruby dan Python dapat merasakan pantulan mereka sendiri tanpa bantuan orang lain. Kita dapat mengatakan bahwa objek Jawa tidak dapat melihat bagaimana tampilannya tanpa cermin, yang merupakan objek dari kelas refleksi, tetapi objek dengan Python dapat melihatnya tanpa cermin. Jadi itu sebabnya kita perlu refleksi di Jawa.
sumber
Dari halaman dokumentasi java
AccessibleObject
memungkinkan penindasan pemeriksaan akses jika diperlukanReflectPermission
.Kelas-kelas dalam paket ini, bersama dengan
java.lang.Class
mengakomodasi aplikasi seperti debugger, juru bahasa, pemeriksa objek, peramban kelas, dan layanan sepertiObject Serialization
danJavaBeans
yang memerlukan akses ke anggota publik dari objek target (berdasarkan kelas runtime-nya) atau anggota yang dideklarasikan oleh kelas yang diberikanIni mencakup fungsionalitas berikut.
Lihatlah tautan dokumentasi ini untuk metode yang diekspos oleh
Class
kelas.Dari artikel ini (oleh Dennis Sosnoski, President, Sosnoski Software Solutions, Inc) dan artikel ini (security-explorations pdf):
Saya bisa melihat banyak kekurangan daripada penggunaan menggunakan Refleksi
Pengguna Refleksi:
Kerugian Refleksi:
Pelanggaran umum:
Lihatlah pertanyaan SE ini mengenai penyalahgunaan fitur refleksi:
Bagaimana cara membaca bidang pribadi di Jawa?
Ringkasan:
Penggunaan fungsi yang tidak aman yang dilakukan dari dalam kode sistem juga dapat dengan mudah menyebabkan kompromi mode keamanan Java l. Jadi gunakan fitur ini dengan hemat
sumber
Woozle
memeriksa kelas lain pada startup untuk melihat mana yang memilikiRegisterAsWoozleHelper()
metode statis , dan memanggil semua metode yang ditemukannya dengan panggilan balik yang dapat mereka gunakan untuk menceritakanWoozle
tentang diri mereka sendiri, menghindari perlu menggunakan Refleksi sementara mis deserializing data.Seperti namanya sendiri itu mencerminkan apa yang dimilikinya misalnya metode kelas, dll selain menyediakan fitur untuk memanggil metode yang membuat instance secara dinamis saat runtime.
Ini digunakan oleh banyak kerangka kerja dan aplikasi di bawah kayu untuk memohon layanan tanpa benar-benar mengetahui kode.
sumber
Refleksi memberi Anda kemampuan untuk menulis kode yang lebih umum. Ini memungkinkan Anda untuk membuat objek saat runtime dan memanggil metodenya saat runtime. Karenanya program dapat dibuat sangat parameter. Hal ini juga memungkinkan introspeksi objek dan kelas untuk mendeteksi variabel dan metodenya yang terpapar ke dunia luar.
sumber
Reflection
memiliki banyak kegunaan . Yang saya lebih akrab dengan, adalah untuk dapat membuat kode dengan cepat.sumber
Saya ingin menjawab pertanyaan ini dengan contoh. Pertama-tama
Hibernate
proyek menggunakanReflection API
untuk menghasilkanCRUD
pernyataan untuk menjembatani jurang antara aplikasi yang berjalan dan toko kegigihan. Ketika hal-hal berubah dalam domain, merekaHibernate
harus tahu tentang mereka untuk bertahan mereka ke penyimpanan data dan sebaliknya.Atau berfungsi
Lombok Project
. Itu hanya menyuntikkan kode pada waktu kompilasi, menghasilkan kode yang dimasukkan ke dalam kelas domain Anda. (Saya pikir itu OK untuk getter dan setter)Hibernate
memilihreflection
karena memiliki dampak minimal pada proses pembuatan aplikasi.Dan dari Java 7 yang kita miliki
MethodHandles
, yang berfungsi sebagaiReflection API
. Dalam proyek, untuk bekerja dengan penebang, kami tinggal menyalin-tempel kode selanjutnya:Karena sulit untuk membuat kesalahan ketik dalam kasus ini.
sumber
Ketika saya menemukan yang terbaik untuk menjelaskan dengan contoh dan tidak ada jawaban yang tampaknya melakukan itu ...
Contoh praktis menggunakan refleksi adalah Server Bahasa Jawa yang ditulis dalam Java atau Server Bahasa PHP yang ditulis dalam PHP, dll. Server Bahasa memberikan kemampuan IDE Anda seperti pelengkapan otomatis, lompat ke definisi, bantuan konteks, tipe petunjuk dan banyak lagi. Untuk memiliki semua nama tag (kata-kata yang dapat dilengkapi secara otomatis) untuk menampilkan semua kemungkinan yang cocok saat Anda mengetik Server Bahasa harus memeriksa segala sesuatu tentang kelas termasuk blok dokumen dan anggota pribadi. Untuk itu perlu refleksi dari kelas tersebut.
Contoh yang berbeda akan menjadi unit-test dari metode pribadi. Salah satu cara untuk melakukannya adalah dengan membuat refleksi dan mengubah ruang lingkup metode kepada publik dalam fase persiapan tes. Tentu saja orang dapat berargumen bahwa metode pribadi tidak boleh diuji secara langsung tetapi bukan itu intinya.
sumber