Artikel ini masih menggunakan contoh-contoh kecil untuk diilustrasikan, karena saya selalu merasa bahwa case-driven adalah yang terbaik, jika tidak jika Anda hanya membaca teorinya, Anda tidak akan memahaminya setelah membacanya. Namun, Anda disarankan untuk melihat kembali teorinya setelah membaca artikel dan memiliki pemahaman yang lebih baik.
Teks utama dimulai di bawah.
[Kasus 1] Dapatkan paket lengkap dan nama kelas melalui objek
Paket mencerminkan; /*** Dapatkan nama paket lengkap dan nama kelas melalui objek**/class demo {// kode lain ...} class hello {public static void main (string [] args) {demo demo = demo baru (); System.out.println (demo.getClass (). GetName ()); }}【Hasil berjalan】: reflect.demo
Tambahkan kalimat: Semua objek kelas sebenarnya adalah contoh kelas.
【Kasus 2】 Objek Kelas Instantiate
Paket mencerminkan; Demo kelas {// kode lain ...} class hello {public static void main (string [] args) {class <?> demo1 = null; Kelas <?> demo2 = null; Kelas <?> demo3 = null; Coba {// umumnya mencoba menggunakan formulir ini demo1 = class.forname ("reflect.demo"); } catch (Exception e) {E.PrintStackTrace (); } demo2 = demo baru (). getClass (); demo3 = Demo.class; System.out.println ("Nama kelas"+demo1.getName ()); System.out.println ("Nama kelas"+demo2.getname ()); System.out.println ("Nama kelas"+demo3.getName ()); }} 【Hasil operasi】:
Kelas namereflect.demo
Kelas namereflect.demo
Kelas namereflect.demo
[Kasus 3] Instantiate objek kelas lain melalui kelas
Objek instantiated dengan membangun non-parameter
orang publik (nama string, usia int) {this.age = usia; this.name = name; }Kemudian terus menjalankan program di atas, dan itu akan muncul:
Jadi, ketika Anda menulis objek yang menggunakan kelas untuk membuat kelas lain, Anda harus mendefinisikan konstruktor Anda sendiri tanpa parameter.
[Case] Panggilan konstruktor di kelas lain melalui kelas (Anda juga dapat membuat objek kelas lain melalui kelas dengan cara ini)
Paket mencerminkan; impor java.lang.reflect.constructor; class person {public orang () {} orang publik (nama string) {this.name = name; } orang publik (usia int) {this.age = usia; } orang publik (nama string, int usia) {this.age = usia; this.name = name; } public string getName () {return name; } public int getage () {usia kembali; } @Override public string toString () {return "["+this.name+""+this.age+"]"; } nama string pribadi; usia int pribadi; } class hello {public static void main (string [] args) {class <?> demo = null; Coba {demo = class.forname ("cermin.person"); } catch (Exception e) {E.PrintStackTrace (); } Orang per1 = null; Orang per2 = null; Orang per3 = null; Orang per4 = null; // Dapatkan semua konstruktor konstruktor <?> Cons [] = demo.getConstructors (); coba {per1 = (orang) kontra [0] .newInstance (); per2 = (orang) kontra [1] .newinstance ("rollen"); per3 = (orang) kontra [2] .newinstance (20); per4 = (orang) kontra [3] .newinstance ("Rollen", 20); } catch (Exception e) {E.PrintStackTrace (); } System.out.println (per1); System.out.println (per2); System.out.println (per3); System.out.println (per4); }}【Hasil operasi】:
[NULL 0]
[Rollen 0]
[NULL 20]
[Rollen 20]
【Kasus】
Mengembalikan antarmuka yang diimplementasikan oleh kelas:
Paket mencerminkan; antarmuka China {public static final string name = "rollen"; Usia int statis publik = 20; public void wellchina (); public void wayshello (nama string, int usia); } class orang mengimplementasikan cina {orang publik () {} orang publik (string sex) {this.sex = sex; } public string getsex () {return sex; } public void setSex (string sex) {this.sex = sex; } @Override public void saychina () {System.out.println ("Hello, China"); } @Override public void sayshello (nama string, int usia) {System.out.println (name+""+usia); } private string sex; } class hello {public static void main (string [] args) {class <?> demo = null; Coba {demo = class.forname ("cermin.person"); } catch (Exception e) {E.PrintStackTrace (); } // simpan semua antarmuka kelas <?> Intes [] = demo.getInterfaces (); untuk (int i = 0; i <intes.length; i ++) {System.out.println ("Antarmuka yang diimplementasikan"+intes [i] .getName ()); }}}【Hasil operasi】:
Implemented Interface Reflect.China
(Perhatikan bahwa contoh -contoh berikut akan menggunakan kelas orang dari contoh ini, jadi untuk menghemat ruang, kami tidak akan lagi menempelkan bagian kode orang di sini, hanya kode kelas utama halo)
【Case】: Dapatkan kelas induk di kelas lain
kelas halo {public static void main (string [] args) {class <?> demo = null; Coba {demo = class.forname ("cermin.person"); } catch (Exception e) {E.PrintStackTrace (); } // Dapatkan kelas kelas induk <?> Temp = demo.getSuperclass (); System.out.println ("Kelas induk yang diwariskan adalah:"+temp.getName ()); }}【Hasil berjalan】
Kelas induk yang diwariskan adalah: java.lang.object
【Kasus】: Dapatkan semua konstruktor di kelas lain
Contoh ini membutuhkan penambahan impor java.lang.reflect.* Di awal program;
Kemudian tulis kelas utama sebagai:
kelas halo {public static void main (string [] args) {class <?> demo = null; Coba {demo = class.forname ("cermin.person"); } catch (Exception e) {E.PrintStackTrace (); } Konstruktor <?> Cons [] = demo.getConstructors (); untuk (int i = 0; i <cons.length; i ++) {System.out.println ("Konstruktor:"+Cons [i]); }}}【Hasil operasi】:
Metode Membangun: Public Reflect.Person ()
Konstruktor: Public Reflect.Person (java.lang.string)
Tetapi pembaca yang cermat akan menemukan bahwa konstruktor di atas tidak memiliki pengubah seperti publik atau pribadi
Mari kita dapatkan pengubah dalam contoh berikut
kelas halo {public static void main (string [] args) {class <?> demo = null; Coba {demo = class.forname ("cermin.person"); } catch (Exception e) {E.PrintStackTrace (); } Konstruktor <?> Cons [] = demo.getConstructors (); untuk (int i = 0; i <cons.length; i ++) {class <?> p [] = cons [i] .getParametertypes (); System.out.print ("Konstruktor:"); int mo = kontra [i] .getModifiers (); System.out.print (Modifier.ToString (Mo)+""); System.out.print (kontra [i] .getName ()); System.out.print ("("); for (int j = 0; j <p.length; ++ j) {System.out.print (p [j] .getName ()+"arg"+i); if (j <p.length-1) {System.out.print (",");}} System.out.println (") {"); }}}【Hasil operasi】:
Konstruktor: Public Reflect.Person () {}
Konstruktor: Public Reflect.Person (java.lang.string arg1) {}
Terkadang mungkin ada pengecualian dalam suatu metode, haha. Mari kita lihat:
kelas halo {public static void main (string [] args) {class <?> demo = null; Coba {demo = class.forname ("cermin.person"); } catch (Exception e) {E.PrintStackTrace (); } Metode metode [] = demo.getMethods (); untuk (int i = 0; i <method.length; ++ i) {class <?> returnType = Method [i] .getReTurnType (); Kelas <?> Para [] = metode [i] .getParameterTypes (); int temp = metode [i] .getModifiers (); System.out.print (Modifier.ToString (temp)+""); System.out.print (returnType.getName ()+""); System.out.print (Metode [i] .getName ()+""); System.out.print ("("); for (int j = 0; j <para.length; ++ j) {System.out.print (para [j] .getName ()+""+"arg"+j); if (j <paragry) {System.out.print (","); if (j <paRA.Length-1) {System.out.print (",");}} {iPece. if (exce.length> 0) {System.out.print (") lemparan"); untuk (int k = 0; k <exce.length; ++ k) {System.out.print (exce [k] .getName ()+""); if (k <exce.length-1) {System.out.print (","); }}}} else {System.out.print (")"); } System.out.println (); }}} 【Hasil operasi】:[Case] Selanjutnya, mari kita dapatkan semua properti dari kelas lain. Akhirnya, saya akan menyelesaikannya bersama, yaitu, untuk mendapatkan seluruh kerangka kelas melalui kelas
kelas halo {public static void main (string [] args) {class <?> demo = null; Coba {demo = class.forname ("cermin.person"); } catch (Exception e) {E.PrintStackTrace (); } System.out.println ("=========================================================================================================== ============================================================================================================================================================== ============================================================================================================================================================== ==================================================================================================================================================== Pengubah Izin int Mo = Field [i] .getModifiers (); System.out.println ("==================================================================================================================================================================================== ========================================================================================================================================================= ====================================================================================================================================================================== ========================================================================================================================================================= fileed1 = demo.getFields (); untuk (int j = 0; j <fileed1.length; j ++) {// pengubah izin int mo = fileed1 [j] .getModifiers (); String priv = Modifier.ToString (MO); // Kelas Jenis Properti <?> Type = FileD1 [j] .getType (); System.out.println (priv + "" + type.getName () + "" + Filed1 [j] .getName () + ";"); }}}【Hasil operasi】:
====================================================
private java.lang.string sex;
===========================================================
java.lang static public static.string nama;
Usia int statis public static;
[Kasus] Faktanya, metode di kelas lain juga dapat dipanggil melalui refleksi:
kelas halo {public static void main (string [] args) {class <?> demo = null; Coba {demo = class.forname ("cermin.person"); } catch (Exception e) {E.PrintStackTrace (); } coba {// Memanggil metode Saychina dalam metode kelas orang Metode = demo.getMethod ("Saychina"); method.invoke (demo.newinstance ()); // Memanggil Metode Sayhello Orang = Demo.GetMethod ("Sayhello", String.Class, Int.Class); Method.invoke (demo.newinstance (), "Rollen", 20); } catch (Exception e) {E.PrintStackTrace (); }}}【Hasil operasi】:
Halo, China
Rollen 20
【Kasus】 Setel dan Dapatkan Metode Kelas Lainnya
kelas halo {public static void main (string [] args) {class <?> demo = null; Objek obj = null; Coba {demo = class.forname ("cermin.person"); } catch (Exception e) {E.PrintStackTrace (); } coba {obj = demo.newInstance (); } catch (Exception e) {E.PrintStackTrace (); } setter (obj, "seks", "pria", string.class); Getter (Obj, "Sex"); } / ** * @param obj * Objek operasi * @param att * atribut operasi * * / public static void getter (objek obj, string att) {coba {metode metode = obj.getClass (). getMethod ("get" + att); System.out.println (Method.Invoke (OBJ)); } catch (Exception e) {E.PrintStackTrace (); }} / ** * @param obj * Objek operasi * @param att * atribut operasi * @param nilai * set nilai * @param tipe * atribut parameter * * / setter void statis publik (objek obj, string, nilai objek, kelas <? method.invoke (OBJ, nilai); } catch (Exception e) {E.PrintStackTrace (); }}} // kelas akhir【Hasil operasi】:
pria
【Kasus】 Operasi dengan refleksi
kelas hello {public static void main (string [] args) melempar pengecualian {class <?> demo = null; Objek obj = null; demo = class.forname ("CLEFLE.PERSON"); obj = demo.newinstance (); Bidang bidang = demo.getDeclaredfield ("sex"); field.setAccessible (true); field.set (obj, "pria"); System.out.println (field.get (OBJ)); }} // kelas akhir[Kasus] Dapatkan dan ubah informasi array melalui refleksi:
impor java.lang.reflect.*; kelas hello {public static void main (string [] args) {int [] temp = {1,2,3,4,5}; Kelas <?> Demo = temp.getClass (). GetComponentType (); System.out.println ("Tipe Array:"+Demo.getName ()); System.out.println ("Panjang Array"+array.getLength (temp)); System.out.println ("Elemen pertama dari array:"+array.get (temp, 0)); Array.set (temp, 0, 100); System.out.println ("Setelah memodifikasi elemen pertama dari array adalah:"+array.get (temp, 0)); }}【Hasil operasi】:
Jenis Array: Int
Panjang array 5
Elemen pertama dari array: 1
Setelah modifikasi, elemen pertama dari array adalah: 100
【Kasus】 Ubah ukuran array melalui refleksi
kelas hello {public static void main (string [] args) {int [] temp = {1,2,3,4,5,6,7,8,9}; int [] newTemp = (int []) arrayinc (temp, 15); cetak (newtemp); System.out.println ("================================================================================================================================ ========================================================================================================================= String []) Arrayinc (ATR, 8); System.arraycopy (Obj, 0, NewarR, 0, CO); Array.getLength (obj);【Hasil operasi】:
Panjang array adalah: 15
1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 =========================================
Panjang array adalah: 8
ABC NULL NULL NULL NULL NULL
Agen dinamis
[Case] Pertama, mari kita lihat cara mendapatkan class loader:
class test {} class hello {public static void main (string [] args) {test t = new test (); System.out.println ("ClassLoader"+t.getClass (). GetClassLoader (). GetClass (). GetName ()); }}【Output program】:
Class Loader Sun.misc.launcher $ appclassloader
Bahkan, ada tiga jenis loader kelas di Java.
1) Bootstrap ClassLoader Loader ini ditulis dalam C ++ dan jarang terlihat dalam pengembangan umum.
2) Extension ClassLoader digunakan untuk memuat kelas yang diperpanjang, umumnya sesuai dengan kelas di direktori JRE/LIB/EXT
3) AppClassLoader memuat kelas yang ditentukan oleh ClassPath dan merupakan loader yang paling umum digunakan. Ini juga merupakan loader default di java.
Jika Anda ingin menyelesaikan proxy dinamis, pertama -tama Anda harus mendefinisikan subkelas antarmuka InvocationHandler, dan operasi spesifik proxy telah selesai.
Paket mencerminkan; impor java.lang.reflect.*; // Tentukan Subjek Antarmuka Antarmuka Proyek {Public String mengatakan (nama string, int usia); } // Tentukan kelas nyata kelas proyek realsubject mengimplementasikan subjek {@Override public string mengatakan (nama string, int usia) {return name + "" + usia; }} kelas myInvocationHandler mengimplementasikan InvocationHandler {private objek obj = null; objek publik mengikat (objek obj) {this.obj = obj; return proxy.newproxyInstance (obj.getClass (). getClassLoader (), obj .getClass (). getInterfaces (), this); } @Override Public Object Invoke (Proxy Object, Metode Metode, Object [] args) melempar Throwable {objek temp = method.invoke (this.obj, args); kembalikan suhu; }} class hello {public static void main (string [] args) {myInvocationHandler demo = myInvocationHandler baru (); Subjek sub = (subjek) demo.bind (new realsubject ()); Info string = sub.say ("rollen", 20); System.out.println (info); }} 【Hasil operasi】:
Rollen 20
Siklus hidup kelas
Setelah kelas dikompilasi, langkah selanjutnya adalah mulai menggunakan kelas. Jika Anda ingin menggunakan kelas, itu pasti tidak dapat dipisahkan dari JVM. Selama eksekusi program, JVM diselesaikan melalui tiga langkah ini: memuat, menghubungkan, dan menginisialisasi.
Pemuatan kelas dilakukan melalui class loader. Loader memuat file biner dari file .class ke dalam area metode JVM dan membuat objek java.lang.class yang menggambarkan kelas ini di area heap. Digunakan untuk merangkum data. Tetapi kelas yang sama hanya akan dimuat oleh loader kelas sebelumnya
Tautan adalah untuk merakit data biner ke dalam keadaan yang dapat dijalankan.
Tautan dibagi menjadi tiga tahap: verifikasi, persiapan dan penguraian
Verifikasi umumnya digunakan untuk mengkonfirmasi apakah file biner ini cocok untuk JVM (versi) saat ini.
Persiapan adalah mengalokasikan ruang memori untuk anggota statis. dan atur nilai default
Parsing mengacu pada proses mengonversi kode di kumpulan konstan sebagai referensi langsung sampai semua referensi simbolik dapat digunakan oleh program yang sedang berjalan (membuat korespondensi lengkap)
Setelah selesai, jenisnya diinisialisasi. Setelah inisialisasi, objek kelas dapat digunakan secara normal. Setelah objek tidak lagi digunakan, itu akan dikumpulkan sampah. Free Up Space.
Ketika tidak ada referensi yang menunjuk ke objek kelas, itu akan dihapus, mengakhiri siklus hidup kelas
Gunakan refleksi untuk mode pabrik
Mari kita lihat mode pabrik jika Anda tidak perlu refleksi:
/ *** @author rollen-holt Mode pabrik dari pola desain*/ antarmuka buah {public abstrak void eat (); } class Apple mengimplementasikan buah {public void eat () {System.out.println ("Apple"); }} kelas oranye mengimplementasikan buah {public void eat () {System.out.println ("Orange"); }} // Bangun kelas pabrik // Dengan kata lain, jika kita hanya perlu memodifikasi kelas pabrik saat menambahkan contoh lain di pabrik kelas masa depan {public static buah getInstance (string fruitname) {buah f = null; if ("apple" .Equals (FruitName)) {f = new Apple (); } if ("oranye" .Equals (FruitName)) {f = New Orange (); } return f; }} class hello {public static void main (string [] a) {buah f = factory.getInstance ("oranye"); prestasi(); }} Dengan cara ini, ketika kita menambahkan subkelas, kita perlu memodifikasi kelas pabrik. Jika kami menambahkan terlalu banyak subclass, kami akan banyak berubah.
Sekarang mari kita lihat mekanisme refleksi yang memanfaatkan:
Paket mencerminkan; Buah antarmuka {public abstrak void eat (); } class Apple mengimplementasikan buah {public void eat () {System.out.println ("Apple"); }} kelas oranye mengimplementasikan buah {public void eat () {System.out.println ("Orange"); }} class factory {public static Fruit getInstance (string className) {buah f = null; coba {f = (buah) class.forname (className) .newInstance (); } catch (Exception e) {E.PrintStackTrace (); } return f; }} class hello {public static void main (string [] a) {fruit f = factory.getInstance ("cermin.apple"); if (f! = null) {f.eat (); }}} Sekarang bahkan jika kita menambahkan sebanyak mungkin subkelas, kelas pabrik tidak perlu dimodifikasi.
Meskipun cinta di atas dapat memperoleh instance antarmuka melalui refleksi, ia perlu melewati paket lengkap dan nama kelas. Selain itu, pengguna tidak dapat mengetahui berapa banyak subclass yang dapat digunakan dalam antarmuka, jadi kami mengkonfigurasi subclass yang diperlukan dalam bentuk file atribut.
Mari kita lihat: mode pabrik menggabungkan file atribut
Pertama -tama buat file sumber daya buah.
Isi adalah:
Apple = Reflect.Apple Orange = Reflect.Ralane
Kemudian tulis kode kelas utama:
Paket mencerminkan; impor java.io.*; impor java.util.*; Buah antarmuka {public abstrak void eat (); } class Apple mengimplementasikan buah {public void eat () {System.out.println ("Apple"); }} kelas oranye mengimplementasikan buah {public void eat () {System.out.println ("Orange"); }} // Operasi kelas file properti init {public static Properties getPro () melempar filenotfoundException, ioException {properties pro = new properties (); File f = file baru ("Fruit.Properties"); if (f.exists ()) {pro.load (FileInputStream baru (f)); } else {pro.setProperty ("apple", "cermin.apple"); pro.setProperty ("Orange", "Reflect.ORANGE"); pro.store (FileOutputStream baru (f), "kelas buah"); } return pro; }} class factory {public static Fruit getInstance (string className) {buah f = null; coba {f = (buah) class.forname (className) .newInstance (); } catch (Exception e) {E.PrintStackTrace (); } return f; }} class hello {public static void main (string [] a) melempar filenotfoundException, ioException {properties pro = init.getPro (); buah f = factory.getInstance (pro.getProperty ("apel")); if (f! = null) {f.eat (); }}} 【Jalankan Hasil】: AppleAnalisis refleksi Java yang mendalam di atas (disarankan) adalah semua konten yang saya bagikan dengan Anda. Saya harap Anda dapat memberi Anda referensi dan saya harap Anda dapat mendukung wulin.com lebih lanjut.