dengan Java5 kita dapat menulis:
Foo[] foos = ...
for (Foo foo : foos)
atau hanya menggunakan Iterable di for loop. Ini sangat berguna.
Namun Anda tidak dapat menulis metode generik untuk iterable seperti ini:
public void bar(Iterable<Foo> foos) { .. }
dan menyebutnya dengan array karena itu bukan Iterable:
Foo[] foos = { .. };
bar(foos); // compile time error
Saya bertanya-tanya tentang alasan di balik keputusan desain ini.
java.lang.reflect.Array
, tetapi kinerjanya lemah. Namun, Anda dapat menulis iterator Anda sendiri (atau implementasi Daftar!) Untuk membungkus array tipe primitif jika Anda mau.Jawaban:
Array dapat mengimplementasikan antarmuka (
Cloneable
danjava.io.Serializable
). Jadi mengapa tidakIterable
? Saya kiraIterable
memaksa menambahkaniterator
metode, dan array tidak menerapkan metode.char[]
bahkan tidak menimpanyatoString
. Pokoknya, array referensi harus dianggap kurang dari ideal - gunakanList
s. Seperti komentar dfa,Arrays.asList
akan melakukan konversi untuk Anda, secara eksplisit.(Karena itu, Anda dapat memanggil
clone
array.)sumber
Iterator<T>
juga membutuhkanremove(T)
, meskipun diizinkan untuk melemparUnsupportedOperationException
.java.lang.Object
.Array adalah Object, tetapi itemnya mungkin bukan. Array mungkin memiliki tipe primitif seperti int, yang tidak bisa diatasi oleh Iterable. Setidaknya itulah yang kurasa.
sumber
Iterable
antarmuka, array primitif harus dikhususkan untuk menggunakan kelas wrapper. Tidak ada yang benar-benar masalah besar, karena semua parameter parameter tetap palsu.List<int>
bukanList<Integer>
, dll). Peretasan dapat dilakukan dengan pembungkus tetapi dengan kehilangan kinerja - dan yang lebih penting - jika peretasan ini dilakukan, peretasan tersebut akan mencegah penerapannya dengan benar di Jawa di masa mendatang (misalnyaint[].iterator()
akan selamanya dikunci untuk kembaliIterator<Integer>
daripadaIterator<int>
). Mungkin, tipe-nilai + generik-spesialisasi yang akan datang untuk Java (proyek valhalla) akan membuat array diimplementasikanIterable
.Array harus didukung
Iterable
, mereka tidak, karena alasan yang sama. NET array tidak mendukung antarmuka yang memungkinkan akses acak hanya baca oleh posisi (tidak ada antarmuka seperti yang didefinisikan sebagai standar). Pada dasarnya, kerangka kerja sering memiliki celah kecil yang menjengkelkan di dalamnya, yang tidak layak waktu untuk diperbaiki. Tidak masalah jika kita dapat memperbaikinya sendiri secara optimal, tetapi seringkali kita tidak bisa memperbaikinya.UPDATE: Agar adil, saya sebutkan .NET array tidak mendukung antarmuka yang mendukung akses acak berdasarkan posisi (lihat juga komentar saya). Namun dalam .NET 4.5 antarmuka yang tepat telah ditentukan dan didukung oleh array dan
List<T>
kelas:Semua masih belum cukup sempurna karena antarmuka daftar yang dapat diubah
IList<T>
tidak mewarisiIReadOnlyList<T>
:Mungkin ada kemungkinan kompatibilitas gotcha dengan perubahan seperti itu.
Jika ada kemajuan pada hal serupa di versi Java yang lebih baru, saya akan tertarik untuk mengetahui di komentar! :)
sumber
IList<T>
memperlihatkan operasi untuk memodifikasi. Akan lebih bagus jikaIList<T>
mewarisi sesuatu sepertiIReadonlyList<T>
antarmuka, yang baru sajaCount
danT this[int]
dan diwarisiIEnumerable<T>
(yang sudah mendukung enumerasi readonly). Hal hebat lainnya adalah antarmuka untuk mendapatkan enumerator urutan terbalik, yang dapat diminta olehReverse
metode ekstensi (sepertiCount
metode ekstensi yang memintaICollection
untuk mengoptimalkan dirinya sendiri.)IList
&ICollection
sejak. NET 1.1, danIList<T>
danICollection<T>
.NET 2.0. Ini adalah kasus lain di mana Jawa jauh di belakang kompetisi.IList
adalah tidak menyediakan atribut yang lebih dapat ditanyakan. Saya akan mengatakan set yang tepat harus mencakup IsUpdateable, IsResizable, IsReadOnly, IsFixedSize, dan ExistingElementsAreImmutable sebagai permulaan. Pertanyaan apakah kode referensi dapat, tanpa typecasting, memodifikasi daftar terpisah dari pertanyaan apakah kode yang menyimpan referensi ke daftar yang tidak seharusnya diubah dapat dengan aman membagikan referensi itu langsung dengan kode luar, atau apakah dapat dengan aman mengasumsikan beberapa aspek dari daftar tidak akan pernah berubah.Sayangnya, array tidak '
class
-cukup'. Mereka tidak mengimplementasikanIterable
antarmuka.Sementara array sekarang objek yang mengimplementasikan Clonable dan Serializable, saya percaya array bukan objek dalam arti normal , dan tidak mengimplementasikan antarmuka.
Alasan Anda dapat menggunakannya dalam untuk-setiap loop adalah karena Sun menambahkan gula sintaks untuk array (ini adalah kasus khusus).
Karena array dimulai sebagai 'hampir objek' dengan Java 1, itu akan menjadi perubahan yang terlalu drastis untuk menjadikannya objek nyata di Jawa.
sumber
Cloneable
danSerializable
antarmuka.Compiler sebenarnya menerjemahkan
for each
pada array menjadifor
loop sederhana dengan variabel counter.Kompilasi yang berikut ini
dan kemudian mendekompilasi hasil file .class
sumber