Menurut Sepecification Bahasa Jawa , edisi ke-3:
Saya ingin memahami mengapa keputusan ini dibuat. Apa yang salah dengan pengecualian umum?
(Sejauh yang saya tahu, obat generik hanyalah kompilasi waktu sintaksis gula, dan mereka akan diterjemahkan ke Object
dalam .class
file, sehingga secara efektif menyatakan kelas generik adalah seolah-olah semua yang ada di dalamnya adalah Object
. Tolong perbaiki saya jika saya salah .)
java
generics
exception
language-design
Hosam Aly
sumber
sumber
myList.get(i)
, jelasget
masih mengembalikan sebuahObject
. Apakah kompiler memasukkan gipsA
untuk menangkap beberapa kendala saat runtime? Jika tidak, OP benar bahwa pada akhirnya akan turun keObject
s saat runtime. (File kelas tentu berisi metadata tentangA
, tetapi itu hanya metadata AFAIK.)Jawaban:
Seperti yang dikatakan oleh tanda, tipe tidak dapat diverifikasi, yang merupakan masalah dalam kasus berikut:
Keduanya
SomeException<Integer>
danSomeException<String>
terhapus ke tipe yang sama, tidak ada cara bagi JVM untuk membedakan instance pengecualian, dan oleh karena itu tidak ada cara untuk mengetahuicatch
blok mana yang harus dieksekusi.sumber
Berikut adalah contoh sederhana cara menggunakan pengecualian:
Tubuh pernyataan COBALAH melempar pengecualian dengan nilai yang diberikan, yang ditangkap oleh klausa tangkapan.
Sebaliknya, definisi pengecualian baru berikut ini dilarang, karena itu menciptakan tipe parameter:
Upaya untuk mengkompilasi laporan di atas kesalahan:
Pembatasan ini masuk akal karena hampir semua upaya untuk menangkap pengecualian seperti itu harus gagal, karena jenisnya tidak dapat diverifikasi. Orang mungkin mengharapkan penggunaan pengecualian sebagai sesuatu seperti berikut ini:
Ini tidak diizinkan, karena jenis dalam klausa tangkapan tidak dapat diverifikasi. Pada saat penulisan ini, kompiler Sun melaporkan kaskade kesalahan sintaksis dalam kasus seperti ini:
Karena pengecualian tidak bisa parametrik, sintaks dibatasi sehingga jenisnya harus ditulis sebagai pengidentifikasi, tanpa parameter berikut.
sumber
Ini pada dasarnya karena dirancang dengan cara yang buruk.
Masalah ini mencegah desain abstrak yang bersih misalnya,
Fakta bahwa klausa tangkapan akan gagal untuk obat generik tidak diverifikasi bukan alasan untuk itu. Kompiler hanya dapat melarang jenis generik beton yang memperpanjang Throwable atau melarang generik di dalam klausa tangkapan.
sumber
EntityNotFoundException
. Tapi itu akan membuat obat generik tidak berguna.Generik diperiksa pada waktu kompilasi untuk ketepatan jenis. Informasi tipe umum kemudian dihapus dalam proses yang disebut tipe erasure . Misalnya,
List<Integer>
akan dikonversi ke jenis non-generikList
.Karena penghapusan tipe , parameter tipe tidak dapat ditentukan pada saat run-time.
Anggaplah Anda diizinkan untuk memperpanjang
Throwable
seperti ini:Sekarang mari kita pertimbangkan kode berikut:
Karena tipe erasure , runtime tidak akan tahu blok tangkapan mana yang harus dieksekusi.
Oleh karena itu adalah kesalahan waktu kompilasi jika kelas generik adalah subclass langsung atau tidak langsung dari Throwable.
Sumber: Masalah dengan tipe erasure
sumber
Saya berharap itu karena tidak ada cara untuk menjamin parameterisasi. Pertimbangkan kode berikut:
Seperti yang Anda perhatikan, parameterisasi hanyalah gula sintaksis. Namun, kompiler mencoba memastikan bahwa parameterisasi tetap konsisten di semua referensi ke objek dalam lingkup kompilasi. Dalam kasus pengecualian, kompiler tidak memiliki cara untuk menjamin bahwa MyException hanya dibuang dari ruang lingkup yang sedang diproses.
sumber