Kelas Lapangan
Kelas bidang mendefinisikan beberapa metode yang dapat digunakan untuk menanyakan jenis bidang dan untuk mengatur atau membaca nilai bidang. Menggabungkan metode ini dengan metode anggota yang diwariskan memungkinkan kami untuk mengetahui semua informasi tentang deklarasi lapangan dan dapat memanipulasi bidang objek atau kelas tertentu.
Metode getGenerictype mengembalikan instance jenis yang mewakili jenis deklarasi bidang. Untuk tipe sepele seperti string atau int, metode ini mengembalikan objek kelas yang terkait dengannya, seperti string.class dan int.classo untuk tipe parameter seperti daftar <stri ng>, metode ini mengembalikan instance parameterizedRype, misalnya, untuk jenis seperti t, metode mengembalikan instance yang dapat diketik.
Metode legacy gettype akan mengembalikan objek kelas dari jenis bidang. Untuk tipe sepele, metode ini berperilaku sama dengan metode getGenerictype. Jika jenis bidang yang dideklarasikan adalah tipe parameterisasi, metode getType akan mengembalikan objek kelas yang sesuai untuk penghapusan jenis parameter, yaitu objek kelas dari tipe asli. Misalnya, untuk suatu objek yang dinyatakan sebagai daftar <stri ng>, getType akan mengembalikan Li St. Class. Jika jenis bidang yang dinyatakan adalah variabel tipe, metode getType akan mengembalikan objek kelas yang sesuai untuk menghapus variabel tipe. Misalnya, misalkan ada kelas foo <ding>, dan untuk bidang yang dinyatakan sebagai tipe T, Getding YPE akan mengembalikan objek.
objek kelas. Jika foo dinyatakan sebagai foo <extends number>, maka ype di bawah get akan mengembalikan nomor.class.
Kita dapat menggunakan metode isenumconstant untuk menanyakan apakah bidang adalah konstanta enum, atau kita dapat menggunakan metode GET dan atur untuk mendapatkan dan mengatur nilai bidang. Metode -metode ini yang menerima kutipan objek dan mengembalikan nilai objek ECT memiliki bentuk yang sama, serta beberapa bentuk yang lebih khusus yang dapat secara langsung menangani tipe dasar. Semua metode ini menerima kutipan untuk menentukan objek yang akan dioperasikan. Untuk bidang statis, kutipan objek ini akan diabaikan, sehingga Anda juga dapat mengaturnya
Diatur ke null. Metode berikut akan mencetak nilai bidang pendek suatu objek:
public static void printshortfield (objek o, nama string) melempar NosuchfieldException, ilegalAccessException {field field = o.getClass (). getField (name); nilai pendek = (pendek) bidang.get (o); System.out.println (nilai);Nilai pengembalian metode GET dapat berupa objek apa pun yang dirujuk oleh bidang ini. Jika bidang adalah tipe primitif, metode ini akan mengembalikan jenis objek kelas pembungkus yang sesuai. Untuk "bidang tipe Hort kami, metode GET mengembalikan objek tipe pendek yang berisi nilai bidang, dan ketika ditugaskan ke nilai variabel lokal, nilai objek akan secara otomatis dibuka kotak.
Penggunaan metode set serupa. Metode pengaturan bidang pendek ke nilai yang disediakan mungkin terlihat seperti ini:
public static voi setshortfield (objek o, nama string, nv pendek) melempar nosuchfieldexception, bidang ilegalaccessException bidang = 0.getClass (). getfield (name); bidang .set (o .nv);
Meskipun SET menerima parameter jenis objek, kita dapat secara langsung memberikan nilai pendek dan membungkusnya menjadi objek pendek dengan konversi pembungkus.
Dalam metode di atas, jika domain objek yang ditentukan tidak dapat diakses dan kontrol akses ini ditegakkan, pengecualian Exception Exception IllegalAccess akan dilemparkan; Jika objek yang lewat berbeda dari jenis domain, pengecualian IllegalargumentException akan dilemparkan; Jika domain tidak statis dan referensi objek yang dilewati adalah nol, pengecualian nullpointerException akan dilemparkan; Mengakses domain statis mungkin memerlukan kelas untuk diinisialisasi, sehingga metode ini juga akan melempar pengecualian exceptionInitializerError.
Kelas lapangan juga memiliki metode khusus untuk mendapatkan dan mengatur tipe dasar. Misalnya, kita dapat memanggil getPrimitive7ype dan mengatur primitive7ype pada objek lapangan, di mana primitive7ype adalah nama tipe dasar (dikapitalisasi). Metode GET dapat digunakan dalam pernyataan berikut:
nilai pendek = field.getshhort (o);
Metode set dapat digunakan dalam pernyataan berikut:
field.setshort (o, nv);
Penggunaan objek tipe pembungkus dapat dihindari dalam pernyataan yang dinyatakan dalam dua cara di atas.
Kelas lapangan mengimplementasikan AnnotatedElement Interface, sehingga kami juga dapat meminta dan menerapkannya ke domain seperti Bagian 16.2.
Catatan tentang.
Dengan metode yang dijelaskan di atas, kita dapat menggunakan objek lapangan sebagai cara untuk memanipulasi nilai apa pun, tetapi kita harus mencoba menghindarinya. Karena bahasa Java menangkap kesalahan pemrograman sebanyak mungkin selama periode kompilasi suatu program, semakin sedikit metode tidak langsung seperti "objek ield" digunakan ketika kita menulis kode, semakin banyak kesalahan yang dapat dicegah sebelum menyusunnya menjadi kode. Selain itu, kita dapat melihat bahwa dalam kode sebelumnya, untuk mengetahui apa yang sebenarnya akan terjadi, kami jelas telah menghabiskan lebih banyak energi untuk membaca kode daripada saat menggunakan nama domain secara langsung dalam sintaks biasa.
Bidang terakhir
Biasanya mengatur bidang yang dinyatakan final akan menyebabkan IllegalAccessException dilemparkan
Pengecualian, inilah yang bisa kita harapkan, karena nilai bidang akhir tidak akan pernah berubah. Tetapi ada beberapa kasus khusus - misalnya, dalam deserialisasi yang disesuaikan (lihat Bagian 20.8.4), masuk akal untuk mengubah nilai bidang akhir, yang hanya dapat kita capai melalui refleksi pada bidang instance, dan hanya jika setAccessible (true) telah dipanggil pada objek lapangan. Perhatikan bahwa itu tidak cukup untuk berhasil memanggil setAccession (benar) dan itu harus disebut.
Kemampuan ini disediakan untuk konteks yang sangat khusus dan bukan untuk tujuan umum, dan kami memperkenalkannya untuk mempertahankan integritas konten saja. Jika Anda berada di luar konteks tertentu, seperti deserialisasi yang disesuaikan, mengubah nilai bidang akhir dapat menyebabkan konsekuensi yang tidak terduga atau bahkan bencana. Di luar konteks ini, tidak ada jaminan bahwa perubahan bidang akhir terlihat. Bahkan dalam konteks seperti itu, perlu untuk memastikan bahwa mekanisme keamanan tidak menghalangi pelaksanaan kode saat pengkodean menggunakan teknologi ini. Mengubah bidang akhir dengan nilai variabel konstan (lihat Bagian 2.2.3) akan membuat perubahan ini tidak terlihat kecuali modifikasi tersebut dicapai dengan menggunakan refleksi.
Kelas Metode
Kelas metode dan metode yang diwariskan dari kelas anggota memungkinkan kami untuk mendapatkan informasi lengkap tentang deklarasi metode:
"Jenis publik getGenericreturntypeo: Metode ini mengembalikan objek tipe dari tipe pengembalian metode target. Jika metode target dinyatakan mengembalikan void, metode ini mengembalikan void.classo
"Jenis Publik [] getGenericparametertypes (): Metode ini mengembalikan array objek jenis dari semua jenis parameter dari metode target, yang akan disimpan dalam array dalam urutan deklarasi parameter. Jika metode target tidak memiliki parameter, metode mengembalikan array kosong.
.publ ic type [] getGeneri cacheti ontypes T: Metode ini mengembalikan array objek jenis dari semua jenis pengecualian yang tercantum dalam klausa lemparan, yang akan disimpan dalam array dalam urutan deklarasi pengecualian.
Jika metode target tidak menyatakan pengecualian, metode ini mengembalikan array kosong.
Java juga menyediakan metode getReTurnType, getParametertypes dan getExceptionTypes untuk mengembalikan CL sebagai "objek alih -alih tipe objek. Sama seperti saat menggunakan field.gettype, variabel tipe parameterisasi dan jenis diwakili oleh objek kelas yang sesuai dengan penghapusannya.
Kelas metode mengimplementasikan AnnotatedElement, dan kami dapat meminta anotasi yang diterapkan pada metode seperti yang dibahas dalam Bagian 16.2. Selain itu, kelas metode ini juga menyediakan getParameterAnnotations untuk menyediakan akses ke anotasi yang diterapkan pada parameter metode. Metode GetParameterAnnotations dapat mengembalikan array anotasi, di mana setiap elemen array terluar sesuai dengan parameter metode; Jika parameter tidak memiliki anotasi, metode ini mengembalikan array anotasi panjang 0 untuk parameter ini. Jika metode yang diwakili oleh objek metode itu sendiri merupakan elemen anotasi, maka metode getDefaultValue akan mengembalikan objek objek yang mewakili nilai default elemen; Jika objek metode itu sendiri bukan elemen anotasi atau tidak memiliki nilai default, maka metode ini akan mengembalikan kelas null.method juga mengimplementasikan genericDeclaration, sehingga metode gettypeParameters didefinisikan, yang akan mengembalikan array objek yang dikotori. Jika objek metode yang diberikan bukan merupakan metode generik, metode ini mengembalikan array kosong.
Kita dapat menggunakan metode isVarArgs untuk memeriksa apakah objek metode adalah metode indeks variabel, dan metode i sbridge dapat digunakan untuk memeriksa apakah itu metode jembatan
Cara paling menarik untuk menggunakan objek metode adalah dengan menyebut dirinya secara reflektif:
. Public Object Invoke (objek di ini, objek ... args) melempar ilegalAccessException, ilegalargumentException, argetException di bawah nVocation: Metode ini menyebut metode yang ditentukan oleh objek metode pada objek ini, dan menggunakan nilai ARG untuk mengatur parameter dari metode yang dipanggil. Untuk metode non-statis, jenis aktual dari ini menentukan implementasi metode mana yang akan dipanggil, sedangkan untuk metode statis, di atas ini akan diabaikan dan biasanya diatur ke nol. Jumlah nilai ARG harus sama dengan jumlah aktual parameter dari metode yang dipanggil, dan jenis nilai -nilai ini harus semua ditetapkan ke parameter metode yang dipanggil; Kalau tidak, kita akan mendapatkan pengecualian LlegalargumentException. Perhatikan bahwa parameter terakhir dari metode kutipan variabel adalah array, jadi kita harus mengisi array dengan kutipan "berubah" yang sebenarnya ingin kita lewati. Jika kita ingin memanggil metode yang tidak kita miliki akses, metode ini akan melempar pengecualian IllegalAccessException. Jika metode yang dipanggil bukan metode On Objek, metode ini akan melempar LlegalargumentExcepti pada pengecualian. Jika OnThiS nol dan non-statis, metode ini akan melempar pengecualian no 1pointerexception. Jika objek metode ini mewakili metode statis dan kelas yang menyatakan metode statis masih dalam keadaan untuk diinisialisasi, metode ini akan melempar pengecualian pekerja pengecualian NitializerError. Jika metode yang dipanggil memiliki kekuatan alien, pengecualian InvocationTargetException akan dilemparkan.
Saat kami menggunakan metode Invoke, kami dapat secara langsung melewati tipe dasar, atau kami dapat menggunakan kelas pembungkus yang sesuai. Jenis yang diwakili oleh kelas pembungkus harus ditetapkan ke jenis parameter yang dinyatakan oleh metode. Kita dapat menggunakan panjang, mengapung atau ganda untuk membungkus kutipan tipe ganda, tetapi kita tidak dapat menggunakan kutipan ganda untuk membungkus tipe panjang atau mengapung, karena ganda tidak dapat ditugaskan untuk panjang atau oat. Metode pemrosesan objek yang dikembalikan dengan metode Invoke sama dengan bidang. Get, yang mengembalikan jenis dasar dari kelas pembungkus yang sesuai dengan mereka. Jika metode ini dinyatakan batal, metode Invoke akan mengembalikan nol,
Sederhananya, ketika kita menggunakan metode panggilan ke panggilan, kita hanya dapat menggunakan parameter hukum dalam bahasa Java.
Pemilih dengan jenis dan nilai yang sama. Misalnya, panggilan berikut
kembalikan str.indexof (".", 8);Itu dapat ditulis dalam bentuk berikut menggunakan refleksi:
Fas yang bisa dilemparkan; coba {Method indexm = string.class. getMethod ("index0f", string.class, int.class); return (integer) indexm.invoke (str, ",", 8); } catch (nosuchmethodException e) {failure = e; } catch (InvocateTargetException e) {fas = e .getCause (); } catch (IllegalAccessException e) {failure = e; } lempar FAS;Meskipun pemeriksaan keamanan kompiler untuk panggilan langsung hanya dapat dilakukan saat menggunakan Invoke pada saat runtime saat menggunakan refleksi, kode berbasis refleksi memang memiliki pemeriksaan keamanan yang setara secara semantik dengan kode yang disebut langsung. Pemeriksaan akses dapat dilakukan dengan cara yang sedikit berbeda - manajer keamanan dapat menolak akses ke metode dalam paket kami, bahkan jika kami dapat memanggilnya secara langsung.
Ketika kita dapat menggunakan bentuk panggilan ini, kita memiliki alasan yang bagus untuk menghindarinya. Tetapi akan masuk akal jika kita menggunakan metode Invoke atau Get/Set saat menulis debugger atau aplikasi generik lainnya yang perlu menafsirkan input pengguna sebagai operasi pada objek. Objek metode dapat digunakan sampai batas tertentu sebagai penunjuk metode yang mirip dengan dalam bahasa lain, tetapi kami memiliki alat yang lebih baik, terutama antarmuka, kelas abstrak, dan kelas bersarang, yang dapat digunakan untuk menangani masalah yang biasanya diselesaikan dengan pointer metode dalam bahasa lain.