Mengapa ketika saya mencoba membuat array dari ArrayLists: ArrayList<Integer>[] arr=new ArrayList<Integer>[40];
ada kesalahan dan java tidak mengizinkan ini?
Apakah ada alasan terkait dengan implementasi java generik, generik dalam bahasa apa pun, atau sesuatu yang sewenang-wenang?
java
language-design
generics
Jakob Weisblat
sumber
sumber
Jawaban:
Ini adalah salah satu lubang utama dalam generik Java, array adalah kovarian , artinya array tipe
Foo[]
adalah subclass dariObject[]
danParentOfFoo[]
. Bandingkan ini denganList<Foo>
yang tidak memiliki perilaku ini.Ini penting ketika Java tidak memiliki obat generik (sampai Java 5) karena jika tidak, sesuatu seperti fungsi penyortiran generik tidak mungkin.
Namun memiliki masalah yang rumit ini, array ingin mengetahui apa tipe mereka saat runtime . Namun obat generik di Jawa didasarkan pada tipe erasure. Kedua hal ini tidak saling berhubungan dengan baik dan di situlah kita mendapatkan masalah kita.
Jadi panjang dan pendeknya adalah, di Jawa 1, array kovarian mengisi sebagian lubang yang dibuat oleh kurangnya obat generik. Namun ketika mereka mencoba mengisi lubang ini dengan benar, kompatibilitas ke belakang berarti bahwa array sangat tidak mungkin untuk diimplementasikan.
Bahkan, lelaki yang benar-benar menciptakan kerangka kerja untuk obat generik, Martin Odersky, membicarakan hal ini di sini selama wawancara tentang mengapa dia membuat Scala. (Cukup menarik jika Anda tertarik pada sejarah Scala sama sekali)
sumber
Sebenarnya, ini agak arbitrer.
Masalahnya adalah bahwa hal itu memungkinkan lubang dalam sistem tipe, karena
ArrayList<T>[]
dapat dicor keObject[]
dan kemudian Anda dapat menempatkanArrayList<U>
dalam array, di manaU != T
.Desainer Java memutuskan untuk memblokir lubang ini dengan sangat bersemangat, dengan tidak mengizinkan
new ArrayList<T>[N]
sama sekali.Namun, itu juga bisa dicolokkan dengan tidak mengizinkan upcasting array generik (tanpa peringatan "tidak dicentang").
sumber
Integer
ke dalamObject[]
yang sebenarnyaString[]
karena array adalah kovarian yang setiap jenis adalah subclass dari objek sehingga ini memberikan kesalahan dalam waktu berjalan karena pengecoran pengecualian. sementara generik invarian jadi ketika dibangun berdasarkan tipe pastikan atau tipe-aman jadi jika tipe tidak suka itu menciptakan tipe itu memberikan kesalahan kompiler.
sumber