Untuk memahami prinsip refleksi, Anda harus terlebih dahulu memahami jenis informasi apa itu. Java memungkinkan kita untuk mengidentifikasi informasi objek dan kelas saat runtime, dan ada dua cara utama: satu adalah RTTI tradisional, yang mengasumsikan bahwa kita sudah tahu semua informasi jenis pada waktu kompilasi; Yang lainnya adalah mekanisme refleksi, yang memungkinkan kita untuk menemukan dan menggunakan informasi kelas saat runtime .
1. Objek Kelas
Untuk memahami bagaimana RTTI bekerja di Java, pertama -tama Anda perlu tahu bagaimana informasi jenis diwakili saat runtime. Ini dilakukan oleh objek kelas, yang berisi informasi yang terkait dengan kelas. Objek kelas digunakan untuk membuat semua objek "biasa". Java menggunakan objek kelas untuk melakukan RTTI, bahkan jika Anda melakukan operasi seperti konversi tipe.
Setiap kelas akan menghasilkan objek kelas yang sesuai, yang disimpan dalam file .class. Semua kelas dimuat secara dinamis ke JVM ketika mereka digunakan untuk pertama kalinya. Kelas ini akan dimuat ketika program membuat referensi ke anggota statis kelas. Objek kelas dimuat hanya saat diperlukan, dan inisialisasi statis dilakukan ketika kelas dimuat.
Public Class TestMain {public static void main (string [] args) {System.out.println (xyz.name);}} class xyz {public string name = "luoxn28"; static {System.out.println ("xyz static block");} xyz public. dibangun ");}}Hasil outputnya adalah:
Loader kelas pertama -tama memeriksa apakah objek kelas kelas ini telah dimuat. Jika belum dimuat, loader kelas default akan mencari file .class yang sesuai berdasarkan nama kelas.
Untuk menggunakan informasi tipe saat runtime, Anda harus mendapatkan referensi ke objek kelas objek (seperti objek dasar). Anda dapat menggunakan fungsi class.forname ("base") untuk mencapai ini, atau menggunakan basis.class. Perhatikan bahwa itu menarik. Saat menggunakan fungsi ".class" untuk membuat referensi ke objek kelas, objek kelas tidak akan diinisialisasi secara otomatis, dan menggunakan forname () akan secara otomatis menginisialisasi objek kelas. Persiapan untuk menggunakan kelas umumnya memiliki 3 langkah berikut:
• Memuat: Diselesaikan oleh class loader, temukan bytecode yang sesuai, dan buat objek kelas
• Tautan: Verifikasi bytecode di kelas dan alokasikan ruang untuk domain statis
• Inisialisasi: Jika kelas memiliki superclass, diinisialisasi, dan inisialisasi statis dan blok inisialisasi statis dijalankan.
Basis kelas publik {static int num = 1; static {system.out.println ("base" + num);}} kelas publik {public static void main (string [] args) {// blok statis tidak akan diinisialisasi kelas clazz1 = base.class; System.out.println ("-----");/ class; Class.forname ("zzz.base");}} 2. Periksa sebelum ketik konversi
Kompiler akan memeriksa apakah jenis transisi ke bawah legal, dan jika tidak legal, pengecualian akan dilemparkan. Sebelum mengonversi tipe turun, Anda dapat menggunakan instanceof untuk menilai.
class Base { }class Derived extends Base { }public class Main {public static void main(String[] args) {Base base = new Derived();if (base instanceof Derived) {// Here you can down-convert System.out.println("ok");}else {System.out.println("not ok");}}} 3. Refleksi: Informasi Runtime
Jika Anda tidak tahu jenis objek yang tepat, RTTI dapat memberi tahu Anda, tetapi ada prasyarat: Jenis ini harus diketahui pada waktu kompilasi sehingga RTTI dapat digunakan untuk mengidentifikasinya. Kelas kelas mendukung refleksi bersama dengan pustaka kelas java.lang.reflect. Perpustakaan kelas ini berisi kelas bidang, metode dan konstruktor. Objek kelas -kelas ini dibuat oleh JVM saat startup untuk mewakili anggota yang sesuai di kelas yang tidak diketahui. Dengan cara ini, Anda dapat menggunakan Kontructor untuk membuat objek baru, menggunakan metode GET () dan Set () untuk mendapatkan dan memodifikasi bidang yang terkait dengan objek bidang di kelas, dan gunakan metode Invoke () untuk memanggil metode yang terkait dengan objek Metode. Selain itu, banyak metode yang nyaman seperti getFields (), getMethods () dan getConstructors () juga dapat dipanggil untuk mengembalikan array yang mewakili bidang, metode, dan objek konstruktor. Dengan cara ini, informasi objek dapat sepenuhnya ditentukan saat runtime tanpa mengetahui apa pun tentang kelas pada waktu kompilasi.
Tidak ada yang ajaib tentang mekanisme refleksi. Saat berhadapan dengan objek tipe yang tidak diketahui melalui refleksi, JVM cukup memeriksa objek untuk melihat kelas spesifik mana yang menjadi miliknya. Oleh karena itu, .Class dari kelas itu harus dapat diambil untuk JVM, baik di mesin lokal atau dari jaringan. Jadi perbedaan nyata antara RTTI dan refleksi hanyalah:
• rtti, kompiler membuka dan memeriksa file .class pada waktu kompilasi
• Renungkan, buka, dan periksa file kelas saat runtime
public class Person implements Serializable {private String name;private int age;// get/set method}public static void main(String[] args) {Person person = new Person("luoxn28", 23);Class clazz = person.getClass();Field[] fields = clazz.getDeclaredFields();for (Field field : fields) {String key = field.getName (); PropertyDescriptor descriptor = new PropertyDescriptor (key, clazz); Metode Metode = deskriptor.getreadmethod (); nilai objek = Method.invoke (orang); System.out.println (Key + ":" + Value);}}} Panggilan di atas fungsi GET dari kelas melalui metode getReadMethod (), dan metode getWritemethod () dapat digunakan untuk memanggil metode yang ditetapkan kelas. Secara umum, kita tidak perlu menggunakan alat refleksi, tetapi mereka lebih berguna dalam membuat kode dinamis. Refleksi digunakan dalam Java untuk mendukung fitur lain seperti serialisasi objek dan JavaBeans.
4. Agen Dinamis
Mode proxy adalah untuk menyediakan operasi tambahan atau berbeda, dan objek yang dimasukkan digunakan untuk menggantikan objek "aktual", yang melibatkan komunikasi dengan objek "aktual", sehingga proxy biasanya bertindak sebagai perantara. Proxy dinamis Java adalah selangkah lebih maju dari gagasan proxy, yang secara dinamis dapat membuat dan proxie dan menangani panggilan ke metode proxy secara dinamis. Semua panggilan yang dilakukan pada proxy dinamis dialihkan ke prosesor panggilan tunggal, dan tugasnya adalah untuk mengungkapkan jenis panggilan dan menentukan kebijakan yang sesuai. Berikut adalah contoh proxy dinamis:
Kelas antarmuka dan implementasi:
Antarmuka Antarmuka Publik {void dosomething (); void SomethingElse (String arg);} kelas publik RealObject mengimplementasikan antarmuka {public void dosomething () {System.out.println ("doSomething.");} public void sesuatu (string arg) {System.out.println. "); Prosesor Objek Proksi Dinamis:
public class DynamicProxyHandler implements InvocationHandler {private Object proxyed;public DynamicProxyHandler(Object proxyed) {this.proxyed = proxyed;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException {System.out.println ("Proxy berfungsi."); Return method.invoke (proxyed, args);}} Kelas Tes:
Kelas publik utama {public static void main (string [] args) {realObject real = new realObject (); antarmuka proxy = (antarmuka) proxy.newproxyInstance (antarmuka.class.getClassLoader (), kelas baru [] {interface.class}, baru DynamicProxyHandler (nyata)); proxy.dosomething (); proxy.somethingelse ("luoxn28");}}Hasil output adalah sebagai berikut:
Anda dapat membuat proxy dinamis dengan memanggil metode proxy proxy proxy.newproxyInstance (). Metode ini memerlukan loader kelas, daftar antarmuka yang Anda ingin proxy terapkan (bukan kelas atau kelas abstrak), dan kelas implementasi InvocationHandler. Proxy dinamis dapat mengarahkan semua panggilan ke prosesor panggilan, sehingga konstruktor prosesor panggilan biasanya memberikan referensi ke objek "aktual", yang akan meneruskan permintaan ketika prosesor panggilan melakukan tugas mediasi.
Di atas adalah pemahaman mendalam tentang refleksi Java yang diperkenalkan oleh editor kepada Anda. Saya harap ini akan membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan dan editor akan membalas Anda tepat waktu. Terima kasih banyak atas dukungan Anda ke situs web Wulin.com!