Kapan menggunakan kelas pembungkus dan tipe primitif

Jawaban:

69

Yang lain telah menyebutkan bahwa konstruksi tertentu seperti Collectionsmembutuhkan objek dan objek memiliki lebih banyak overhead daripada rekan primitifnya (memori & tinju).

Pertimbangan lainnya adalah:

Ini dapat berguna untuk menginisialisasi Objek ke nullatau mengirim nullparameter ke dalam metode / konstruktor untuk menunjukkan status atau fungsi. Ini tidak bisa dilakukan dengan primitif.

Banyak programmer menginisialisasi angka ke 0 (default) atau -1 untuk menandakan ini, tetapi tergantung pada skenarionya, ini mungkin salah atau menyesatkan.

Ini juga akan mengatur adegan NullPointerExceptionketika ada sesuatu yang digunakan secara tidak benar, yang jauh lebih ramah programmer daripada beberapa bug sewenang-wenang di telepon.

pstanton
sumber
15
"Ini dapat berguna untuk menginisialisasi Objek ke null". Ini tidak bisa berguna karena ini tidak benar, jika bidangnya opsional, Anda harus menunjukkannya secara eksplisit.
Eddie Jamsession
8
lol @ EddieJamsession terima kasih, saya tidak akan pernah menginisialisasi ke nol lagi. (pfffft)
pstanton
@EddieJamsession Jika menginisialisasi Objek ke null sebagai cara untuk menunjukkan kegagalan saat menyetel nilai sebenarnya telah gagal, bagaimana lagi yang Anda usulkan untuk mengatasi masalah ini? Oh, saya baru menyadari saat saya mengetik ini: pengecualian. NullPointerException terlalu umum; akan lebih baik menggunakan pengecualian ubahsuaian yang sangat spesifik untuk menunjukkan apa yang salah. Bagus, saya akan melakukannya mulai sekarang ...
klaar
1
@EddieJamsession Setelah membaca tentang masalah ini, saya telah menemukan konsep objek opsional. Baik.
klaar
18

Umumnya, Anda harus menggunakan tipe primitif kecuali Anda membutuhkan objek karena alasan tertentu (misalnya untuk dimasukkan ke dalam koleksi). Meski begitu, pertimbangkan pendekatan berbeda yang tidak memerlukan objek jika Anda ingin memaksimalkan kinerja numerik. Hal ini disarankan oleh dokumentasi , dan artikel ini menunjukkan bagaimana auto-boxing dapat menyebabkan perbedaan kinerja yang besar.

Matthew Flaschen
sumber
3
kinerja yang terpukul tidak begitu bagus sehingga keterbacaan / keandalan kode harus mengambil kursi belakang.
pstanton
2
Pertama, menggunakan primitif dengan tepat tidak akan membuat kode Anda tidak terbaca. Kedua, pencapaian kinerja signifikan dalam beberapa kasus. Tidak masuk akal untuk mengatakan itu tidak pernah terjadi.
Matthew Flaschen
1
@pstanton: tolong jelaskan bagaimana Integerlebih terbaca daripada int.
Stephen C
Dalam banyak kasus Integer tidak lebih terbaca daripada int dan dalam kasus ini saya akan selalu menggunakan int, atau jika saya tahu variabel tertentu TIDAK PERNAH menjadi null, saya akan menggunakan int karena int adalah seperti yang Anda tunjukkan sedikit lebih efisien. Namun, dalam banyak kasus, lebih mudah bagi programmer lain untuk memahami status variabel ketika sebuah objek digunakan, karena dapat diinisialisasi ke null untuk menandakan bahwa ia belum siap. Misalnya jika Anda memiliki catatan database yang belum disimpan yang memiliki id numerik bertambah unik, haruskah id ini menjadi 0, -1 atau null sebelum diberi id yang valid? Dalam hal ini, Objek lebih baik.
pstanton
berkenaan dengan kinerja - dalam kasus khusus, kinerja yang dicapai dapat menjadi signifikan, yaitu jika Anda membuat banyak Objek ini dengan sangat cepat atau jika banyak dari mereka yang menumpuk selama periode waktu tertentu. Namun, saya mengharapkan programmer yang layak untuk dapat mengidentifikasi kasus-kasus khusus ini, baik hindari atau ubah sesuai. Saya tidak pernah mengatakan bahwa ini TIDAK PERNAH signifikan, namun secara umum, tidak.
pstanton
12

Menurut pendapat saya, jika anggota kelas saya adalah variabel pembungkus, itu tidak bergantung pada nilai default, yang merupakan perilaku ramah pengembang.

1.

class Person {
   int SSN ; // gets initialized to zero by default 
}

2.

class PersonBetter {
  Integer SSN; //gets initialized to null by default
}

Dalam kasus pertama, Anda tidak dapat membiarkan nilai SSN tidak diinisialisasi. Ini mungkin menyakitkan jika Anda tidak memeriksa apakah nilai telah ditetapkan sebelum Anda mencoba menggunakannya.

Dalam kasus kedua, Anda dapat membiarkan SSN diinisialisasi dengan null. Yang dapat mengarah ke NullPointerException tetapi lebih baik daripada tanpa sadar memasukkan nilai default (nol) sebagai SSN ke database setiap kali Anda mencoba menggunakannya tanpa menginisialisasi bidang SSN.

Cody
sumber
3
Pola pembangun dimaksudkan untuk menyiasati ini. Dalam skenario ini, Anda membuat PersonBuilderyang memunculkan pengecualian jika SSN tidak disetel sebelum memanggil "build" untuk mendapatkan Personinstance. Saya pikir hal semacam ini berlebihan, tetapi itulah yang dipromosikan oleh bahasa Java untuk pola yang tepat.
Sandy Chapman
8

Saya hanya akan menggunakan jenis pembungkus jika Anda harus.

Dalam menggunakannya Anda tidak mendapatkan banyak keuntungan, selain fakta bahwa mereka Objects.

Dan, Anda kehilangan overhead dalam penggunaan memori dan waktu yang dihabiskan untuk tinju / unboxing.

jjnguy
sumber
4
Anda mungkin tidak mendapatkan banyak, tetapi Anda juga tidak kehilangan banyak. kecuali jika Anda menjalankan pilot sawit tahun 1990-an.
pstanton
Fakta bahwa mereka adalah Objek juga memberi mereka lebih banyak konteks dan enkapsulasi daripada sebagai primitif biasa. Jadi, Anda sebenarnya bisa mendapatkan banyak tergantung pada tujuan primitif itu dan di mana mereka digunakan.
aberrant80
4

Praktis saya pernah mengalami situasi di mana penggunaan kelas pembungkus dapat dijelaskan.

Saya membuat kelas layanan yang memiliki longvariabel tipe

  1. Jika variabel berjenis long- saat tidak diinisialisasi, akan disetel ke 0 - ini akan membingungkan pengguna saat ditampilkan di GUI
  2. Jika variabel berjenis Long- saat tidak diinisialisasi, akan disetel ke null- nilai null ini tidak akan muncul di GUI.

Ini berlaku Booleanjuga di mana nilai bisa lebih membingungkan ketika kita menggunakan primitif boolean(karena nilai defaultnya salah).

Mohamed Afzal
sumber
3

Koleksi adalah kasus umum untuk objek pembungkus Java sederhana. Namun, Anda mungkin mempertimbangkan untuk memberikan Wrapper arti yang lebih spesifik dalam kode (objek nilai).

IMHO hampir selalu ada manfaat untuk menggunakan objek nilai ketika itu bermuara pada keterbacaan dan pemeliharaan kode. Membungkus struktur data sederhana di dalam objek ketika mereka memiliki tanggung jawab tertentu seringkali menyederhanakan kode. Ini adalah sesuatu yang sangat penting dalam Desain Berdasarkan Domain .

Tentu saja ada masalah kinerja, tetapi saya cenderung mengabaikannya sampai saya memiliki kemungkinan untuk mengukur kinerja dengan data yang tepat dan melakukan tindakan yang lebih terarah ke area bermasalah. Mungkin juga lebih mudah untuk memahami masalah kinerja jika kodenya juga mudah dipahami.

Mattias Holmqvist
sumber
3

kinerja aplikasi yang didominasi oleh kalkulasi numerik bisa mendapatkan keuntungan besar dari penggunaan primitif.

tipe primitif, seseorang menggunakan operator ==, tetapi untuk pembungkus pilihan yang lebih disukai adalah memanggil metode equals ().

"Jenis primitif dianggap berbahaya" karena mereka mencampur "semantik prosedural ke dalam model berorientasi objek yang seragam.

Banyak programmer menginisialisasi angka ke 0 (default) atau -1 untuk menandakan ini, tetapi tergantung pada skenarionya, ini mungkin salah atau menyesatkan.

loknath
sumber
1

Jika Anda ingin menggunakan Koleksi, Anda harus menggunakan kelas Wrapper.

Tipe primitif, digunakan untuk array. Juga, untuk merepresentasikan data yang tidak memiliki perilaku, misalnya, penghitung, atau kondisi boolean.

Sejak autoboxing, batas "kapan harus menggunakan primitif atau pembungkus" menjadi sangat kabur.

Tapi ingat, Wrappers adalah objek, jadi Anda mendapatkan semua fitur Java yang keren. Misalnya, Anda dapat menggunakan refleksi untuk membuat objek Integer, tetapi tidak untuk nilai int. Kelas pembungkus juga memiliki metode seperti valueOf.

Tom
sumber
Selain Koleksi, Saya Tidak Harus Menggunakan Kelas Pembungkus? Bagaimana jika menggunakannya untuk deklarasi biasa seperti Integer i = new Integer (10); Apakah baik melakukan seperti ini?
Gopi
autoboxing memungkinkan Anda melakukan Integer i = 10;
Tom
1
Tidak, Sri. Jika Anda tidak memiliki persyaratan bahwa saya menjadi objek, jangan menjadikannya satu.
Matthew Flaschen
Autoboxing akan membuka kotak yang dinyatakan di atas i ke int i = 10 atau Integer i = 10?
Gopi
3
int pi = new Integer (10); bekerja. Integer oi = 10; bekerja. int ni = null; tidak bekerja. LHS diubah menjadi apapun yang RHS butuhkan.
pstanton
0

Jika Anda ingin membuat tipe nilai. Sesuatu seperti ProductSKU atau AirportCode.

Ketika tipe primitif (string dalam contoh saya) mendefinisikan kesetaraan, Anda ingin mengganti kesetaraan.

Chris Missal
sumber
5
string bukanlah primitif
pstanton
2
masih ada alasan bagus untuk membungkus tipe nilai yang berisi string sebagai objek dasarnya.
Chris Missal
jawaban Anda tidak masuk akal. saya tidak yakin apa yang Anda katakan. Saya setuju dengan komentar Anda, kelas pembungkus adalah ide yang bagus jika mereka meningkatkan keterbacaan.
pstanton
Jenis nilai atau objek nilai harus dibuat dan tidak dapat diubah. Misalnya, tidak masuk akal untuk membuat objek "CountryCode" seperti: new CountryCode ("USA") lalu membuat objek lain dengan cara yang sama, yang nantinya akan berbeda. Mereka hanya string untuk memulai, tetapi mereka memiliki makna di baliknya. Dengan menggunakan string, Anda dapat memodifikasinya (dengan menambahkan lebih banyak data, dll) tetapi tidak lagi sama. Lihat artikel ini untuk penjelasan yang lebih baik tentang apa yang saya coba jelaskan :) Saya harap ini masuk akal c2.com/cgi/wiki?ValueObject
Chris Missal
0

Nilai primitif di Java bukanlah objek. Untuk memanipulasi nilai-nilai ini sebagai objek, paket java.lang menyediakan kelas pembungkus untuk setiap tipe data primitif.

Semua kelas Wrapper bersifat final. Objek dari semua kelas pembungkus yang dapat dimulai tidak dapat diubah yang berarti nilai dalam objek pembungkus tidak dapat diubah.

Meskipun, kelas void dianggap sebagai kelas pembungkus tetapi tidak menggabungkan nilai primitif dan tidak dapat dimulai. Itu tidak memiliki konstruktor publik, itu hanya menunjukkan objek kelas yang mewakili kata kunci void.

Ahmad Sayeed
sumber