1. Pendahuluan
Refleksi Java adalah mekanisme yang memungkinkan kita untuk mendapatkan informasi internal metode kelas, sifat, kelas orang tua, antarmuka, dll. Saat runtime. Dengan kata lain, refleksi pada dasarnya adalah proses "terbalik". Ketika kami membuat instance dari kelas melalui new , itu sebenarnya dibangun oleh mesin virtual Java berdasarkan objek Class kelas ini saat runtime, dan refleksi adalah untuk mendapatkan informasi definisi melalui objek Class suatu kelas, sehingga kami dapat mengakses sifat dan metodenya, mengetahui kelas induk dari kelas ini, antarmuka mana yang diimplementasikan, dan informasi lainnya.
2. Kelas
Kita tahu bahwa menggunakan Javac dapat menyusun file .java menjadi file .class, yang berisi informasi definisi asli kami untuk kelas (kelas induk, antarmuka, konstruktor, properti, metode, dll.). File .class akan dimuat ke Java Virtual Machine (JVM) ClassLoader saat runtime. Ketika file .class dimuat, JVM akan menghasilkan objek kelas untuk itu. Objek yang kami instantiate melalui baru dalam program sebenarnya dibangun berdasarkan objek kelas yang sesuai saat runtime. Lebih tepatnya, objek kelas ini sebenarnya adalah instance dari kelas generik java.lang.Class<T> . Misalnya, objek Class<MyClass> adalah instance Class<T> yang merangkum informasi definisi dari kelas MyClass . Karena kelas java.lang.Class<T> tidak memiliki konstruktor publik, kami tidak dapat instantiate kelas ini secara langsung. Kita bisa mendapatkan objek kelas melalui metode berikut.
Dalam penjelasan berikut, kami akan mengikuti kelas orang dan kelas siswa sebagai contoh:
People Public Class {Private String Name; usia int pribadi; orang publik (nama string, int usia) {this.name = name; this.age = usia; } public int getage () {usia kembali; } public string getName () {return name; } public void setage (int usia) {this.age = usia; } public void setName (name string) {this.name = name; } public void speak () {System.out.println (getName () + "" + getage ()); }} siswa kelas publik memperluas orang {private int grade; siswa publik (nama string, int usia) {super (nama, usia); } siswa publik (nama string, usia int, grade int) {super (nama, usia); this.grade = grade; } public int getGrade () {return grade; } public void setGrade (int grade) {this.grade = grade; } private void belajar (kursus string) {System.out.println (Nama + "Learn" + kursus); }} Dapatkan Objek Kelas dengan Nama Kelas
Jika kita tahu nama kelas selama periode kompilasi, kita bisa mendapatkan objek kelasnya seperti ini:
Class <e People> peopleClass = people.class;
Ada juga metode untuk mendapatkan objek kelas berdasarkan nama jalur lengkap kelas sebagai berikut:
// Misalkan kelas People ada di kelas paket com.test <dia> peopleClass = class.forname ("com.test.people"); Perhatikan bahwa parameter metode Class.forName() harus menjadi nama jalur lengkap dari suatu kelas. Faktanya, selama kita "mengimpor com.test.people", kita dapat secara langsung mendapatkan objek kelasnya melalui " People.class " tanpa harus menulis jalur lengkap. (Jika kelas yang sesuai tidak ditemukan di classpath saat memanggil metode Class.forName() , ClassNotFoundException akan dilemparkan.)
Dapatkan objek kelasnya melalui objek itu sendiri
Orang -orang = orang baru ("Bill", 18); Class <delas> peopleClass = people.getClass (); Dapatkan konstruktor kelas dengan refleksi
Setelah kami memperoleh objek kelas People , kami dapat memperoleh informasi definisi asli dari kelas People melalui objek kelas ini. Pertama, mari kita dapatkan objek konstruktor dari kelas People . Dengan objek konstruktor ini, kita dapat membangun objek People . Misalnya, kami dapat menambahkan kode berikut di Student.java:
public static void main (string [] args) {class <e People> pclass = people.class; Coba {konstruktor <e- orang> konstruktor = pclass.getConstructor (string.class, int.class); People People = Constructor.Newinstance ("Bill", 18); obj.speak (); } catch (Exception e) {}} Di atas, kami menyebut metode getConstructor untuk mendapatkan objek konstruktor dari kelas People . Karena konstruktor kami ingin mendapatkan parameter formal dari String tipe dan int , kami lulus di String.class dan int.class . Dengan objek konstruktor, kita dapat memanggil metode newInstance untuk membuat objek people .
Perhatikan bahwa ketika Constructor kelas, Method , dan objek Field diperoleh melalui refleksi, sebelum memanggil metode objek ini, bendera accessible dari objek ini diatur ke true untuk membatalkan pemeriksaan akses bahasa Java, yang dapat meningkatkan kecepatan refleksi. Seperti yang ditunjukkan dalam kode berikut:
Constructor <eurs> constructor = peopleClass.getConstructor (String.class, int.class); // Atur properti konstruktor yang dapat diakses untuk membatalkan Java Access Check Constructor.setAccessible (true);
Mendapatkan metode yang dinyatakan di kelas melalui refleksi
Dapatkan metode yang dinyatakan di kelas saat ini (tidak termasuk diwarisi dari kelas induk)
Untuk mendapatkan semua metode dinyatakan di kelas saat ini, Anda dapat menggunakan fungsi getDeclaredMethods di kelas. Ini akan mendapatkan semua metode yang dinyatakan di kelas saat ini (termasuk metode private , public , static dan lainnya). Ini akan mengembalikan array objek Method , dan setiap objek Method mewakili metode yang dinyatakan dalam kelas. Untuk mendapatkan metode yang ditentukan, Anda dapat menghubungi getDeclaredMethod(String name, Class...<T> parameterTypes) .
Seperti yang ditunjukkan dalam kode berikut:
private static void showDeclaredMethods () {siswa siswa = siswa baru ("bill", 18); // Dapatkan semua metode yang dinyatakan oleh metode kelas siswa [] Metode = student.getClass (). GetDeclaredMethods (); Coba {// Dapatkan Objek LearnMethod (Encapsulated Metode Learn) Metode LearnMethod = Student.getClass (). GetDeclaredMethod ("Learn", String.class); // Dapatkan daftar parameter dari metode belajar dan cetak kelas <?> [] ParamClasses = learnmethod.getParameterTypes (); untuk (class <?> class: paramClasses) {System.out.println ("Pelajari Parameter Metode:" + class.getName ()); } // menilai apakah metode pembelajarannya adalah private System.out.println (learnmethod.getName () + "adalah pribadi" + Modifier.isprivate (learnmethod.getModifiers ()))); // Panggil metode belajar learnmethod.invoke (siswa, "refleksi java"); } catch (Exception e) {}} Dapatkan metode publik yang dinyatakan di kelas saat ini dan kelas induk
Untuk mendapatkan kelas saat ini dan semua metode public dideklarasikan di kelas induk, Anda dapat memanggil fungsi getMethods , dan untuk mendapatkan metode public yang ditentukan, Anda dapat memanggil metode getMethod . Silakan lihat kode berikut:
private static void showmethods () {siswa siswa = siswa baru ("Mr.Simple"); // Dapatkan semua metode publik (termasuk siswa itu sendiri dan diwarisi dari kelas orang tua) metode [] Metode = student.getClass (). GetMethods (); Coba {// Perhatikan bahwa hanya metode publik yang dapat diperoleh melalui getMethod. Jika Anda mencoba mendapatkan metode pribadi, pengecualian akan dilemparkan. Metode LearnMethod = Student.getClass (). GetMethod ("Learn", String.Class); } catch (Exception e) {}} Dapatkan atribut yang didefinisikan di kelas dengan refleksi
Mendapatkan atribut mirip dengan mendapatkan metode, kecuali bahwa panggilan untuk getMethods() / getDeclaredMethods() diganti dengan metode panggilan untuk getFields() / getDeclaredFields() .
Dapatkan atribut yang didefinisikan dalam kelas saat ini (tidak termasuk atribut yang diwarisi dari kelas induk)
Untuk mendapatkan semua atribut yang ditentukan dalam kelas saat ini (termasuk berbagai atribut seperti private , public , static , dll.), Anda dapat memanggil fungsi getDeclaredFields dari objek kelas; Untuk mendapatkan atribut yang ditentukan, Anda dapat menghubungi getDeclaredField .
Seperti yang ditunjukkan dalam kode berikut:
private static void showDeclaredFields () {student student = baru siswa ("bill", 18); // Dapatkan semua atribut yang didefinisikan dalam bidang kelas saat ini [] bidang = student.getClass (). GetDeclaredFields (); coba {// dapatkan bidang atribut yang ditentukan gradefield = student.getClass (). getDeclaredfield ("grade"); // Dapatkan atribut value system.out.println ("Nilai adalah:" + gradefield.getint (siswa)); // Atur nilai atribut gradefield.set (siswa, 10); } catch (Exception e) {}} Dapatkan atribut publik yang didefinisikan di kelas saat ini dan kelas induk
Untuk mendapatkan semua properti public yang didefinisikan di kelas saat ini dan kelas induk, Anda dapat memanggil fungsi getFields dari objek Class . Untuk mendapatkan properti public yang ditentukan, Anda dapat menghubungi metode getField , seperti yang ditunjukkan pada kode berikut:
private static void showfields () {siswa siswa = siswa baru ("bill", 18); // Dapatkan semua properti publik dari kelas saat ini dan bidang kelas induk [] publicFields = student.getClass (). GetFields (); } Refleksi untuk mendapatkan kelas induk kelas dan antarmuka yang diimplementasikan oleh kelas
Dapatkan Kelas Orang Tua
Panggil saja metode getSuperClass dari objek Class , seperti yang ditunjukkan pada kode berikut:
Siswa Siswa = Siswa Baru ("Bill", 18); kelas <?> Superclass = student.getClass (). GetSuperclass (); Dapatkan antarmuka yang diimplementasikan
Untuk mengetahui antarmuka mana yang diterapkan oleh kelas, cukup panggil metode getInterfaces dari objek Class , seperti yang ditunjukkan pada kode berikut:
private static void showInterfaces () {Student Student = New Student ("Bill", 19); Kelas <?> [] Antarmuka = student.getClass (). GetInterfaces ();}Meringkaskan
Di atas adalah seluruh konten artikel ini. Saya berharap ini akan membantu untuk belajar dan bekerja semua orang.