Saya ingin mencoba menjabarkan jawaban dari @DerMike untuk menjelaskan:
Pertama, tipe erasure tidak berarti bahwa JDK dihilangkan informasi tipe saat runtime. Ini adalah metode untuk memungkinkan kompatibilitas jenis waktu kompilasi dan jenis runtime untuk hidup berdampingan dalam bahasa yang sama. Seperti yang disiratkan oleh blok kode ini, JDK menyimpan informasi tipe yang terhapus - hanya saja tidak terkait dengan gips dan barang yang diperiksa.
Kedua, ini memberikan informasi jenis generik ke kelas generik tepat satu tingkat di atas hirarki dari jenis beton yang diperiksa - yaitu kelas induk abstrak dengan parameter tipe generik dapat menemukan jenis beton yang sesuai dengan parameter jenisnya untuk implementasi beton itu sendiri. yang secara langsung mewarisi darinya. Jika kelas ini non-abstrak dan instantiated, atau implementasi konkret adalah dua tingkat turun, ini tidak akan berhasil (walaupun sedikit jimmying dapat membuatnya berlaku untuk jumlah level yang telah ditentukan di luar satu, atau naik ke kelas terendah dengan parameter tipe X generik, dan lain-lain).
Pokoknya, lanjut ke penjelasan. Ini kodenya lagi, dipisahkan menjadi beberapa baris untuk memudahkan referensi:
1 # Kelas genericParameter0OfThisClass =
2 # (Kelas)
3 # ((ParameterizedType)
4 # getClass ()
5 # .getGenericSuperclass ())
6 # .getActualTypeArguments () [0];
Mari 'kita' menjadi kelas abstrak dengan tipe generik yang berisi kode ini. Bacalah ini dengan kasar dari dalam ke luar:
- Baris 4 mendapatkan instance Kelas konkret saat ini. Ini mengidentifikasi tipe konkret keturunan langsung kita.
- Baris 5 mendapatkan supertype kelas itu sebagai Tipe; Inilah kita. Karena kita adalah tipe parametrik, kita dapat dengan aman mengarahkan diri kita ke ParameterizedType (baris 3). Kuncinya adalah bahwa ketika Java menentukan objek Tipe ini, ia menggunakan informasi tipe yang ada pada anak untuk mengaitkan informasi tipe dengan parameter tipe kami dalam instance ParameterizedType yang baru. Jadi sekarang kita dapat mengakses jenis beton untuk obat generik kita.
- Baris 6 mendapatkan array tipe yang dipetakan ke dalam obat generik kami, seperti yang dinyatakan dalam kode kelas. Untuk contoh ini kita tarik parameter pertama. Ini kembali sebagai Type.
- Baris 2 menampilkan Tipe terakhir yang dikembalikan ke Kelas. Ini aman karena kita tahu tipe apa yang bisa diambil oleh parameter tipe generik kita dan dapat mengonfirmasi bahwa semuanya akan menjadi kelas (saya tidak yakin bagaimana di Jawa kita bisa mendapatkan parameter generik yang tidak memiliki instance Class terkait dengan itu, sebenarnya).
... dan itu sudah cukup. Jadi kami mendorong info jenis dari implementasi konkret kami sendiri kembali ke diri kami sendiri, dan menggunakannya untuk mengakses pegangan kelas. kita bisa menggandakan getGenericSuperclass () dan naik dua level, atau menghilangkan getGenericSuperclass () dan mendapatkan nilai untuk diri kita sendiri sebagai tipe konkret (peringatan: Saya belum menguji skenario ini, mereka belum mendatangi saya).
Akan menjadi rumit jika anak-anak Anda yang konkret menjadi jumlah hop yang sewenang-wenang pergi, atau jika Anda konkret dan tidak final, dan terutama rumit jika Anda mengharapkan anak-anak Anda (yang sangat dalam) memiliki obat generik sendiri. Tetapi Anda biasanya dapat mendesain pertimbangan-pertimbangan itu, jadi ini yang paling membantu Anda.
Semoga ini bisa membantu seseorang! Saya tahu posting ini kuno. Saya mungkin akan memotong penjelasan ini dan menyimpannya untuk pertanyaan lain.