Koleksi Java hanya menyimpan Objek, bukan tipe primitif; bagaimanapun kita bisa menyimpan kelas pembungkus.
Mengapa kendala ini?
java
collections
types
primitive-types
JavaUser
sumber
sumber
class
, melainkan oleh JVM. Pernyataan tersebutint i = 1
mendefinisikan pointer ke instance tunggal dari objek yang didefinisikanint
di JVM, yang disetel ke nilai yang1
ditentukan di suatu tempat di JVM. Ya, pointer di Java - ini hanya disarikan dari Anda oleh implementasi bahasa. Primitif tidak dapat digunakan sebagai Generik karena predikat bahasa semua jenis generik harus dari supertipeObject
- itulah mengapaA<?>
dikompilasi keA<Object>
pada saat run-time.Jawaban:
Itu adalah keputusan desain Java, dan beberapa orang menganggapnya sebagai kesalahan. Wadah menginginkan Objek dan primitif tidak berasal dari Objek.
Ini adalah satu tempat dimana desainer .NET belajar dari JVM dan menerapkan tipe nilai dan generik sehingga tinju dihilangkan dalam banyak kasus. Di CLR, container generik dapat menyimpan tipe nilai sebagai bagian dari struktur container yang mendasarinya.
Java memilih untuk menambahkan dukungan generik 100% di kompiler tanpa dukungan dari JVM. JVM apa adanya, tidak mendukung objek "non-objek". Java generics memungkinkan Anda untuk berpura-pura tidak ada pembungkus, tetapi Anda tetap membayar harga kinerja tinju. Ini PENTING untuk kelas program tertentu.
Tinju adalah kompromi teknis, dan saya merasa ini adalah detail implementasi yang bocor ke dalam bahasa. Autoboxing adalah gula sintaksis yang bagus, tetapi masih merupakan penalti kinerja. Jika ada, saya ingin kompilator memperingatkan saya saat kotak otomatis. (Sejauh yang saya tahu, mungkin sekarang, saya menulis jawaban ini di tahun 2010).
Penjelasan yang bagus tentang SO tentang tinju: Mengapa beberapa bahasa membutuhkan Boxing dan Unboxing?
Dan kritik terhadap generik Java: Mengapa beberapa orang mengklaim bahwa implementasi Java generik buruk?
Dalam pembelaan Java, mudah untuk melihat ke belakang dan mengkritik. JVM telah bertahan dalam ujian waktu, dan merupakan desain yang baik dalam banyak hal.
sumber
Object.ReferenceEquals
referensi tipeObject
yang mengidentifikasi bilangan bulat kotak, tetapi seharusnya tidak legal untuk meneruskan nilai integer]. Pembongkaran otomatis Java adalah IMHO hanya buruk.Membuat implementasi lebih mudah. Karena primitif Java tidak dianggap sebagai Objek, Anda perlu membuat kelas koleksi terpisah untuk masing-masing primitif ini (tidak ada kode template untuk dibagikan).
Anda dapat melakukannya, tentu saja, lihat saja GNU Trove , Apache Commons Primitives, atau HPPC .
Kecuali jika Anda memiliki koleksi yang sangat besar, biaya overhead untuk pembungkus tidak cukup menjadi masalah bagi orang-orang untuk peduli (dan ketika Anda memiliki koleksi primitif yang sangat besar, Anda mungkin ingin menghabiskan usaha untuk melihat menggunakan / membangun struktur data khusus untuk mereka ).
sumber
Ini kombinasi dari dua fakta:
int
bukanObject
)List<?>
benar-benarList<Object>
pada saat run-time)Karena keduanya benar, koleksi Java generik tidak dapat menyimpan tipe primitif secara langsung. Untuk kenyamanan, autoboxing diperkenalkan untuk memungkinkan tipe primitif otomatis dimasukkan kotak sebagai tipe referensi. Namun, jangan salah, koleksi tersebut tetap menyimpan referensi objek.
Bisakah ini dihindari? Mungkin.
int
adalahObject
, maka tidak perlu untuk jenis kotak sama sekali.sumber
Ada konsep auto-boxing dan auto-unboxing. Jika Anda mencoba untuk menyimpan
int
diList<Integer>
kompiler Java akan secara otomatis mengubahnya menjadi fileInteger
.sumber
Ini bukan kendala, kan?
Pertimbangkan jika Anda ingin membuat koleksi yang menyimpan nilai primitif. Bagaimana Anda akan menulis koleksi yang dapat menyimpan int, atau float atau char? Kemungkinan besar Anda akan mendapatkan banyak koleksi, jadi Anda akan membutuhkan intlist dan charlist, dll.
Memanfaatkan sifat berorientasi objek dari Java saat Anda menulis kelas koleksi, ia dapat menyimpan objek apa pun sehingga Anda hanya memerlukan satu kelas koleksi. Ide ini, polimorfisme, sangat kuat dan sangat menyederhanakan desain perpustakaan.
sumber
Saya pikir kita mungkin melihat kemajuan dalam ruang ini di JDK mungkin di Java 10 berdasarkan JEP ini - http://openjdk.java.net/jeps/218 .
Jika Anda ingin menghindari tinju primitif dalam koleksi saat ini, ada beberapa alternatif pihak ketiga. Selain opsi pihak ketiga yang disebutkan sebelumnya, ada juga Koleksi Eclipse , FastUtil , dan Koloboke .
Perbandingan peta primitif juga diterbitkan beberapa waktu lalu dengan judul: Ikhtisar HashMap Besar: JDK, FastUtil, Goldman Sachs, HPPC, Koloboke, Trove . Koleksi GS Collections (Goldman Sachs) telah dimigrasi ke Eclipse Foundation dan sekarang menjadi Eclipse Collections.
sumber
Alasan utamanya adalah strategi desain java. ++ 1) Koleksi membutuhkan objek untuk manipulasi dan primitif bukan berasal dari objek sehingga ini bisa menjadi alasan lain. 2) tipe data primitif Java bukan tipe referensi untuk ex. int bukanlah sebuah obyek.
Untuk mengatasi:-
kami memiliki konsep auto-boxing dan auto-unboxing. jadi jika Anda mencoba untuk menyimpan tipe data primitif, kompilator akan secara otomatis mengubahnya menjadi objek dari kelas data primitif tersebut.
sumber