(1). Jenis antarmuka yang terkait dengan refleksi + generik
java.lang.reflect.Type: Antarmuka induk umum untuk semua tipe dalam bahasa java
java.lang.reflect.ParameterizedType
java.lang.reflect.GenericArrayType
java.lang.reflect.WildcardType
1. Ketik sub-antarmuka langsung
Empat jenis antarmuka: ParameterizedType, GenericArrayType, TypeVariable, dan WildcardType
ParameterizedType: mewakili tipe berparameter, seperti Koleksi
GenericArrayType: mewakili tipe array yang tipe elemennya adalah tipe berparameter atau variabel tipe
TypeVariable: adalah antarmuka induk umum untuk berbagai jenis variabel
WildcardType: mewakili ekspresi tipe wildcard, seperti ?, ? extends Number, ? super Integer [wildcard adalah sebuah kata: ini adalah "wildcard"]
2. Tipe langsung mengimplementasikan subkelas: Kelas kelas
3. antarmuka java.lang.reflect.Type
Semua tipe Tipe mengacu pada: tipe mentah (tipe mentah) [sesuai dengan Kelas], tipe berparameter (tipe berparameter) [sesuai dengan Tipe Parameter], tipe array (tipe array) [sesuai dengan GenericArrayType], variabel tipe (variabel tipe) [ sesuai dengan TypeVariable ], tipe data dasar (tipe primitif) [masih sesuai dengan Kelas]
4. antarmuka java.lang.reflect.ParameterizedType
Arti tipe antarmuka ParameterizedType
Mewakili tipe berparameter. Misalnya: tipe berparameter seperti Map
Dapatkan tipe aktual dalam tipe berparameter<>
Pernyataan kode sumber: Type[] getActualTypeArguments();
[Catatan] Tidak peduli berapa banyak level <> yang bersarang di <>, metode ini hanya menghapus <> terluar dan konten yang tersisa digunakan sebagai nilai kembalian dari metode ini.
metode E statis publikIV(
Daftar Array> al1,
Daftar Array al2,
Daftar Array al3,
Nomor ArrayListtextends> al4,
Daftar Array al5){}
Kemudian setiap parameternya umumnya bertipe parametrik.
{1}. Untuk ArrayList>, setelah kembali melalui getActualTypeArguments(), setelah menghapus <> terluar, tipe yang tersisa adalah ArrayList. Oleh karena itu, tipe kembalian untuk parameter ini adalah ParameterizedType.
{2}. Untuk ArrayList, setelah kembali melalui getActualTypeArguments(), setelah menghapus <> terluar, tipe yang tersisa adalah E. Oleh karena itu, tipe kembalian untuk parameter ini adalah TypeVariable.
{3}. Untuk ArrayList, setelah kembali melalui getActualTypeArguments(), setelah menghapus <> terluar, tipe yang tersisa adalah String. Oleh karena itu tipe kembalian untuk parameter ini adalah Kelas.
{4}. Untuk ArrayListtextends Number>, setelah kembali melalui getActualTypeArguments(), setelah menghapus <> terluar, tipe yang tersisa adalah? Oleh karena itu, tipe kembalian untuk parameter ini adalah WildcardType.
{5}. Untuk ArrayList, setelah kembali melalui getActualTypeArguments(), setelah menghapus <> terluar, tipe yang tersisa adalah E[]. Oleh karena itu, tipe kembalian untuk parameter ini adalah GenericArrayType.
Oleh karena itu, dimungkinkan untuk memperoleh parameter aktual dari berbagai tipe, jadi demi penyatuan, array kelas induk langsung Type[] digunakan untuk penerimaan.
4. antarmuka java.lang.reflect.GenericArrayType
Arti tipe antarmuka GenericArrayType
Mewakili tipe array generik. Misalnya: metode batal(Daftar Array[] al){…}
[Catatan] <> tidak dapat muncul dalam inisialisasi array, yaitu <> tidak dapat muncul setelah array baru, jika tidak, javac tidak akan lolos. Tapi itu baik-baik saja sebagai variabel referensi atau parameter suatu metode.
Dapatkan tipe elemen dalam array generik
Deklarasi kode sumber: Ketik getGenericComponentType();
[Catatan] Tidak peduli berapa banyak [] yang disandingkan dari kiri ke kanan, metode ini hanya menghapus [] paling kanan dan konten sisanya digunakan sebagai nilai kembalian metode ini.
Mengapa tipe nilai kembalian Tipe?
metode E statis publikV(String[] p1,E[] p2,ArrayList[] p3,E[][] p4){}{1}. Untuk String[], setelah kembali melalui getComponentType(), setelah menghapus [] paling kanan, tipe yang tersisa adalah String. Oleh karena itu tipe kembalian untuk parameter ini adalah Kelas
{2}. Untuk E[], setelah kembali melalui getComponentType(), setelah menghapus [] paling kanan, tipe yang tersisa adalah E. Oleh karena itu, tipe kembalian untuk parameter ini adalah TypeVariable
{3}. Untuk ArrayList[], setelah kembali melalui getComponentType(), setelah menghapus [] paling kanan, tipe yang tersisa adalah ArrayList. Oleh karena itu, tipe kembalian untuk parameter ini adalah ParameterizedType
{4}. Untuk E[][], setelah kembali melalui getComponentType(), setelah menghapus [] paling kanan, tipe yang tersisa adalah E[]. Oleh karena itu, tipe kembalian untuk parameter ini adalah GenericArrayType
5. antarmuka java.lang.reflect.GenericArrayType
Arti dari tipe antarmuka TypeVariable
Mewakili parameter tipe atau disebut juga variabel tipe. Misalnya: E dalam metode void(E e){} adalah variabel tipe
Mendapatkan tipe batas atas variabel tipe yang memenuhi syarat generik
Pernyataan kode sumber: Type[] getActualTypeArguments();
[Catatan] Ini hanyalah batas atas. Alasannya adalah variabel tipe hanya dapat menggunakan perluasan untuk membatasi (beberapa) batas ketika variabel tersebut didefinisikan. Super tidak dapat digunakan, jika tidak, kompilasi tidak akan lolos. Pada saat yang sama, extends memberikan batas atas variabel tipe.
Mengapa tipe pengembaliannya berupa array? Karena variabel tipe dapat dikualifikasikan dengan beberapa batas atas dengan &, terdapat beberapa batas atas, sehingga tipe nilai yang dikembalikan adalah tipe array [].
Misalnya saja cara berikut ini:
public static extends Map& Cloneable&Serializable> Metode EVI(E e){…}Batas atas pertama E adalah Map, yang merupakan tipe ParameterizedType
Batas atas kedua dari E adalah Cloneable, yang merupakan tipe Kelas
Oleh karena itu, untuk penyatuan, tipe elemen dari array nilai yang dikembalikan adalah Tipe
6. antarmuka java.lang.reflect.WildcardType
Arti tipe antarmuka WildcardType
Ekspresi yang mewakili tipe wildcard.
Misalnya, void printColl(ArrayListal); di ?
[Catatan] Menurut komentar API di atas: pada tahap ini, ekspresi wildcard hanya menerima batas atas atau batas bawah. Ini berbeda dengan saat mendefinisikan variabel tipe, yang dapat menentukan beberapa batas atas. Namun API mengatakan bahwa untuk menjaga skalabilitas, tipe nilai kembalian di sini ditulis dalam bentuk array. Faktanya, ukuran array yang dikembalikan sekarang adalah 1
Mendapatkan tipe batas atas objek ekspresi wildcard yang memenuhi syarat generik
Pernyataan kode sumber: Type[] getUpperBounds();
[Catatan] Seperti disebutkan di atas, ukuran array di Type[] yang dikembalikan pada tahap ini adalah 1. Ditulis sebagai Type[ ] adalah ekstensi untuk peningkatan bahasa.
Misalnya saja cara berikut ini:
{1}. voidprintColl statis publik(ArrayListends ArrayList> al){}
Ekspresi wildcardnya adalah: ? extendsArrayList, sehingga extends diikuti oleh batas atas ?, dan batas atas ini adalah tipe ParameterizedType.
{2}. voidprintColl statis publik(ArrayListends E> al){}
Ekspresi wildcardnya adalah: ? extends E, sehingga extends diikuti oleh batas atas dari ?, dan batas atas ini adalah tipe TypeVariable
{3}.public static voidprintColl(ArrayListends E[]> al){}
Ekspresi wildcardnya adalah: ? extends E[], sehingga extends diikuti oleh batas atas ?, dan batas atas ini bertipe GenericArrayType
{4}.public static voidprintColl(ArrayListends Number> al){}
Ekspresi wildcardnya adalah: ? extends Number, sehingga extends diikuti oleh batas atas ?, dan batas atas ini adalah tipe Class
Akhirnya disatukan menjadi Type sebagai tipe elemen array.
7. Asal Tipe dan sub-antarmukanya
1. Jenis sebelum munculnya obat generik
Jika tidak ada obat generik, yang ada hanya disebut tipe primitif. Pada saat ini, semua tipe primitif diabstraksi melalui kelas file bytecode Kelas Kelas. Objek konkrit dari kelas Class mewakili tipe primitif tertentu.
2. Jenis setelah munculnya obat generik
Setelah munculnya obat generik, tipe data diperluas. Dari hanya tipe primitif, tipe berparameter, tipe tipe variabel, tipe parameter berkualifikasi generik (termasuk karakter pengganti + ekspresi berkualifikasi karakter pengganti), dan tipe array generik telah diperluas.
3. Alasan mengapa tipe-tipe yang berkaitan dengan generik tidak dapat disatukan dengan tipe-tipe asli ke dalam Kelas
[1]. [Penyebab penghapusan umum]
Awalnya, tipe yang baru dihasilkan + tipe primitif harus disatukan ke dalam objek tipe file bytecode masing-masing. Tapi karena obat generik awalnya bukan bahan di Jawa. Jika obat generik benar-benar ditambahkan, ini melibatkan modifikasi set instruksi JVM, yang sangat fatal.
[2]. [Cara memperkenalkan obat generik di Java]
Untuk memanfaatkan obat generik tanpa benar-benar memperkenalkannya, Java menggunakan mekanisme penghapusan generik untuk memperkenalkan obat generik. Generik di Java hanya digunakan oleh kompiler javac untuk memastikan keamanan data dan menghindari masalah konversi tipe paksa. Namun, setelah kompilasi selesai, semua tipe yang terkait dengan obat generik akan dihapus.
[3]. [Kelas tidak dapat mengekspresikan tipe yang terkait dengan obat generik]
Oleh karena itu, tipe berparameter yang terkait dengan generik, tipe variabel tipe, tipe parameter berkualifikasi generik (termasuk karakter pengganti + ekspresi berkualifikasi wildcard), dan tipe array generik semuanya dikembalikan ke bentuk aslinya dan disimpan dalam file bytecode setelah obat generik dihapus, dan tidak ada file bytecode yang konsisten dengan tipenya sendiri. Oleh karena itu, tipe baru yang diperluas terkait dengan obat generik tidak dapat disatukan ke dalam kelas Kelas.
(4). Representasi tipe-tipe yang berhubungan dengan obat generik di Java
Untuk mengoperasikan tipe ini melalui refleksi guna memenuhi kebutuhan pengembangan aktual, Java telah menambahkan ParameterizedType, GenericArrayType, TypeVariable, dan WildcardType untuk mewakili tipe yang tidak dapat diklasifikasikan ke dalam kelas Kelas tetapi memiliki nama yang sama dengan tipe aslinya.
(5). Pengenalan Tipe: menyatukan tipe-tipe yang berkaitan dengan Kelas tipe generik dan primitif
[Alasan memperkenalkan Type]
Untuk skalabilitas program, antarmuka Type akhirnya diperkenalkan sebagai antarmuka induk umum untuk Kelas, ParameterizedType, GenericArrayType, TypeVariable dan WildcardType. Dengan cara ini, parameter tipe Tipe menerima parameter aktual dari lima subtipe di atas atau tipe nilai yang dikembalikan adalah parameter tipe Tipe.
[Alasan mengapa tidak ada metode di antarmuka Type]
Seperti terlihat di atas, kemunculan Type hanya berperan meningkatkan skalabilitas program melalui polimorfisme, dan tidak memiliki efek lain. Oleh karena itu, tidak ada metode dalam kode sumber antarmuka Type.