Ini bisa menjadi pertanyaan paling bodoh yang pernah diajukan tetapi saya pikir itu cukup membingungkan bagi seorang pemula Java.
- Adakah yang bisa menjelaskan apa yang dimaksud dengan abadi ?
- Mengapa tidak
String
berubah? - Apa kelebihan / kekurangan benda yang tidak bisa diubah?
- Mengapa objek yang bisa berubah seperti
StringBuilder
lebih disukai daripada String dan sebaliknya?
Contoh yang bagus (di Jawa) akan sangat dihargai.
java
string
immutability
ashokgelal
sumber
sumber
Jawaban:
Immutable berarti bahwa begitu konstruktor untuk objek telah menyelesaikan eksekusi, instance itu tidak dapat diubah.
Ini berguna karena ini berarti Anda dapat meneruskan referensi ke objek di sekitarnya, tanpa khawatir orang lain akan mengubah isinya. Terutama ketika berhadapan dengan concurrency, tidak ada masalah penguncian dengan objek yang tidak pernah berubah
misalnya
Foo
tidak perlu khawatir bahwa penelepongetValue()
dapat mengubah teks dalam string.Jika Anda membayangkan kelas yang mirip dengan
Foo
, tetapi denganStringBuilder
bukanString
sebagai anggota, Anda dapat melihat bahwa penelepongetValue()
akan dapat mengubahStringBuilder
atributFoo
instance.Berhati-hatilah dengan berbagai jenis ketidakberdayaan yang mungkin Anda temukan: Eric Lippert menulis artikel blog tentang ini. Pada dasarnya Anda dapat memiliki objek yang antarmukanya tidak dapat diubah tetapi di balik layar, keadaan aktual yang dapat berubah menjadi privat (dan karenanya tidak dapat dibagi dengan aman di antara utas).
sumber
Objek yang tidak dapat diubah adalah objek di mana bidang internal (atau setidaknya, semua bidang internal yang memengaruhi perilaku eksternalnya) tidak dapat diubah.
Ada banyak keuntungan dari string yang tidak dapat diubah:
Kinerja: Lakukan operasi berikut:
C yang mendasarinya untuk metode substring () mungkin kira-kira seperti ini:
Perhatikan bahwa tidak ada karakter yang harus disalin! Jika objek String dapat diubah (karakter dapat berubah nanti) maka Anda harus menyalin semua karakter, jika tidak, perubahan karakter dalam substring akan tercermin dalam string lain nanti.
Konkurensi: Jika struktur internal objek yang tidak dapat diubah valid, itu akan selalu valid. Tidak ada kemungkinan bahwa utas berbeda dapat membuat keadaan tidak valid dalam objek itu. Oleh karena itu, objek yang tidak berubah adalah Thread Safe .
Pengumpulan sampah: Jauh lebih mudah bagi pemulung untuk membuat keputusan logis tentang benda-benda yang tidak dapat diubah.
Namun, ada juga kerugian untuk ketidakberubahan:
Kinerja: Tunggu, saya pikir Anda mengatakan kinerja terbalik dari kekekalan! Ya, terkadang, tapi tidak selalu. Ambil kode berikut:
Kedua baris tersebut menggantikan karakter keempat dengan huruf "a". Tidak hanya potongan kode kedua yang lebih mudah dibaca, tetapi juga lebih cepat. Lihatlah bagaimana Anda harus melakukan kode yang mendasari untuk foo. Substring mudah, tetapi sekarang karena sudah ada karakter di ruang lima dan sesuatu yang lain mungkin merujuk foo, Anda tidak bisa begitu saja mengubahnya; Anda harus menyalin seluruh string (tentu saja beberapa fungsi ini diabstraksi menjadi fungsi dalam C yang mendasarinya, tetapi intinya di sini adalah untuk menunjukkan kode yang dieksekusi semua di satu tempat).
Perhatikan bahwa concatenate dipanggil dua kali yang berarti bahwa seluruh string harus diulang! Bandingkan ini dengan kode C untuk
bar
operasi:Operasi string yang bisa berubah jelas jauh lebih cepat.
Kesimpulan: Dalam kebanyakan kasus, Anda ingin string yang tidak dapat diubah. Tetapi jika Anda perlu melakukan banyak menambahkan dan memasukkan ke dalam string, Anda membutuhkan kemampuan untuk berubah-ubah. Jika Anda ingin manfaat keamanan konkurensi dan pengumpulan sampah bersamanya kuncinya adalah menjaga objek Anda yang bisa berubah-ubah tetap lokal ke suatu metode:
Karena
mutable
objek adalah referensi lokal, Anda tidak perlu khawatir tentang keamanan konkurensi (hanya satu utas yang pernah menyentuhnya). Dan karena itu tidak direferensikan di tempat lain, itu hanya dialokasikan pada stack, jadi itu dialokasikan segera setelah panggilan fungsi selesai (Anda tidak perlu khawatir tentang pengumpulan sampah). Dan Anda mendapatkan semua manfaat kinerja dari mutabilitas dan imutabilitas.sumber
Passing pointers because Java is pass-by-reference
Bukankah java "pass-by-value?"Sebenarnya String tidak dapat diubah jika Anda menggunakan definisi wikipedia yang disarankan di atas.
Status string memang mengubah konstruksi pasca. Lihatlah metode kode hash (). String cache nilai kode hash di bidang lokal tetapi tidak menghitungnya sampai panggilan pertama kode hash (). Evaluasi malas hashcode ini menempatkan String dalam posisi yang menarik sebagai objek yang tidak berubah yang keadaannya berubah, tetapi tidak dapat diamati telah berubah tanpa menggunakan refleksi.
Jadi mungkin definisi yang tidak berubah harus menjadi objek yang tidak dapat diamati telah berubah.
Jika keadaan berubah pada objek yang tidak dapat diubah setelah dibuat tetapi tidak ada yang dapat melihatnya (tanpa refleksi) apakah objek tersebut masih tidak dapat diubah?
sumber
Objek yang tidak dapat diubah adalah objek yang tidak dapat diubah secara terprogram. Mereka sangat baik untuk lingkungan multi-threaded atau lingkungan lain di mana lebih dari satu proses dapat mengubah (bermutasi) nilai-nilai dalam suatu objek.
Hanya untuk memperjelas, bagaimanapun, StringBuilder sebenarnya adalah objek yang bisa berubah, bukan yang tidak dapat diubah. String java biasa tidak dapat diubah (artinya setelah dibuat, Anda tidak dapat mengubah string yang mendasarinya tanpa mengubah objek).
Sebagai contoh, katakanlah saya memiliki kelas bernama ColoredString yang memiliki nilai String dan warna String:
Dalam contoh ini, ColoredString dikatakan bisa berubah karena Anda dapat mengubah (bermutasi) salah satu properti kuncinya tanpa membuat kelas ColoredString baru. Alasan mengapa ini mungkin buruk adalah, misalnya, katakanlah Anda memiliki aplikasi GUI yang memiliki banyak utas dan Anda menggunakan ColoredStrings untuk mencetak data ke jendela. Jika Anda memiliki instance dari ColoredString yang telah dibuat sebagai
Maka Anda akan mengharapkan string selalu menjadi "Biru". Namun, jika ada utas lainnya, dapatkan contoh ini dan menelepon
Anda tiba-tiba, dan mungkin secara tak terduga, sekarang memiliki string "Merah" ketika Anda menginginkan yang "Biru". Karena itu, objek yang tidak berubah hampir selalu lebih disukai ketika melewati contoh objek di sekitar. Ketika Anda memiliki kasus di mana objek yang dapat ditukar benar-benar diperlukan, maka Anda biasanya akan menjaga objek dengan hanya memberikan salinan dari bidang kontrol spesifik Anda.
Untuk rekap, di Jawa, java.lang.String adalah objek yang tidak dapat diubah ( tidak dapat diubah setelah dibuat) dan java.lang.StringBuilder adalah objek yang dapat diubah karena dapat diubah tanpa membuat instance baru.
sumber
String s1 = "String lama";
String s2 = s1;
s1 = "String Baru";
sumber
"abadi" berarti Anda tidak dapat mengubah nilai. Jika Anda memiliki turunan dari kelas String, metode apa pun yang Anda panggil yang tampaknya mengubah nilai, sebenarnya akan membuat String lain.
Untuk mempertahankan perubahan, Anda harus melakukan sesuatu seperti ini foo = foo.sustring (3);
Immutable vs bisa berubah bisa lucu ketika Anda bekerja dengan koleksi. Pikirkan tentang apa yang akan terjadi jika Anda menggunakan objek yang bisa berubah sebagai kunci untuk peta dan kemudian ubah nilainya (tip: pikirkan tentang
equals
danhashCode
).sumber
waktu java
Mungkin agak terlambat tetapi untuk memahami apa objek abadi, pertimbangkan contoh berikut dari Java 8 Date and Time API ( java.time ) baru. Seperti Anda mungkin tahu semua objek tanggal dari Java 8 tidak dapat diubah, jadi dalam contoh berikut
Keluaran:
Ini mencetak tahun yang sama dengan tanggal awal karena
plusYears(2)
mengembalikan objek baru sehingga tanggal lama masih tidak berubah karena ini adalah objek yang tidak dapat diubah. Setelah dibuat, Anda tidak dapat memodifikasinya lebih lanjut dan variabel tanggal masih menunjukkannya.Jadi, contoh kode itu harus menangkap dan menggunakan objek baru yang dipakai dan dikembalikan oleh panggilan itu ke
plusYears
.sumber
Saya sangat menyukai penjelasan dari SCJP Sun Certified Programmer untuk Java 5 Study Guide .
sumber
Objek yang tidak berubah tidak dapat mengubah kondisinya setelah dibuat.
Ada tiga alasan utama untuk menggunakan objek yang tidak dapat diubah kapan pun Anda bisa, yang semuanya akan membantu mengurangi jumlah bug yang Anda perkenalkan dalam kode Anda:
Ada juga beberapa optimisasi lain yang mungkin dapat Anda buat dalam kode ketika Anda tahu bahwa keadaan suatu objek tidak berubah - misalnya caching hash yang dihitung - tetapi ini adalah optimisasi dan oleh karena itu hampir tidak begitu menarik.
sumber
Satu makna berkaitan dengan bagaimana nilai disimpan di komputer, Untuk string .Net misalnya, itu berarti bahwa string dalam memori tidak dapat diubah, Ketika Anda berpikir Anda mengubahnya, Anda sebenarnya membuat yang baru string dalam memori dan menunjuk variabel yang ada (yang hanya pointer ke kumpulan karakter aktual di tempat lain) ke string baru.
sumber
s1="Hi"
: sebuah objeks1
dibuat dengan nilai "Hai" di dalamnya.s2=s1
: sebuah objeks2
dibuat dengan referensi ke objek s1.s1="Bye"
: nilais1
objek sebelumnya tidak berubah karenas1
memiliki tipe String dan tipe String adalah tipe yang tidak dapat diubah, sebagai gantinya kompiler membuat objek String baru dengan nilai "Bye" dans1
merujuknya. di sini ketika kita mencetaks2
nilai, hasilnya akan menjadi "Hai" bukan "Sampai jumpa" karenas2
direferensikan kes1
objek sebelumnya yang memiliki nilai "Hai".sumber
Immutable berarti bahwa setelah objek dibuat, yang bukan anggota akan berubah.
String
tidak dapat diubah karena Anda tidak dapat mengubah kontennya. Sebagai contoh:Dalam kode di atas, string s1 tidak berubah, objek lain (
s2
) dibuat menggunakans1
.sumber
Immutable berarti tidak dapat diubah atau tidak dapat dimodifikasi. Setelah objek string dibuat, data atau statusnya tidak dapat diubah
Pertimbangkan contoh di bawah ini,
Mari mendapatkan ide dengan mempertimbangkan diagram di bawah ini,
Dalam diagram ini, Anda dapat melihat objek baru yang dibuat sebagai "Dunia Masa Depan". Tetapi tidak mengubah "Masa Depan".
Because String is immutable
.s
, masih merujuk ke "Masa Depan". Jika Anda perlu memanggil "Dunia Masa Depan",Mengapa objek string tidak dapat diubah di java?
sumber
Setelah diterapkan, tidak dapat diubah. Pertimbangkan kelas yang instance dapat digunakan sebagai kunci untuk hashtable atau serupa. Lihatlah praktik terbaik Java.
sumber
Objek yang Tidak Berubah
Suatu objek dianggap tidak berubah jika kondisinya tidak dapat berubah setelah dibangun. Ketergantungan maksimum pada objek yang tidak dapat diubah diterima secara luas sebagai strategi yang bagus untuk membuat kode yang sederhana dan andal.
Objek yang tidak dapat berubah sangat berguna dalam aplikasi berbarengan. Karena mereka tidak dapat mengubah keadaan, mereka tidak dapat rusak oleh gangguan utas atau diamati dalam keadaan tidak konsisten.
Pemrogram sering enggan untuk menggunakan objek yang tidak dapat diubah, karena mereka khawatir tentang biaya membuat objek baru sebagai lawan memperbarui objek di tempat. Dampak penciptaan objek sering kali terlalu tinggi, dan dapat diimbangi oleh beberapa efisiensi yang terkait dengan objek yang tidak dapat diubah. Ini termasuk penurunan overhead karena pengumpulan sampah, dan penghapusan kode yang diperlukan untuk melindungi objek yang bisa berubah dari korupsi.
Subbagian berikut mengambil kelas yang instansnya berubah dan berasal kelas dengan instance yang tidak dapat diubah darinya. Dengan melakukan hal itu, mereka memberikan aturan umum untuk konversi semacam ini dan menunjukkan beberapa keuntungan dari objek yang tidak dapat diubah.
Sumber
sumber
Karena jawaban yang diterima tidak menjawab semua pertanyaan. Saya terpaksa memberi jawaban setelah 11 tahun dan 6 bulan.
Semoga Anda maksud objek yang tidak dapat diubah (karena kita dapat memikirkan referensi yang tidak dapat diubah ).
Objek tidak berubah : jika pernah dibuat, mereka selalu mewakili nilai yang sama (tidak memiliki metode apa pun yang mengubah nilai).
Hormati definisi di atas yang dapat diperiksa dengan melihat ke dalam kode sumber Sting.java .
lebih aman dari bug.
lebih mudah dimengerti.
dan lebih siap untuk perubahan.
Mempersempit pertanyaan Mengapa kita membutuhkan StringBuilder yang bisa berubah dalam pemrograman? Penggunaan umum untuk itu adalah untuk menggabungkan sejumlah besar string bersama, seperti ini:
Menggunakan string yang tidak dapat diubah, ini membuat banyak salinan sementara - nomor pertama dari string ("0") sebenarnya disalin n kali dalam proses membangun string terakhir, angka kedua disalin n-1 kali, dan sebagainya di. Sebenarnya biaya O (n2) waktu hanya untuk melakukan semua penyalinan itu, meskipun kita hanya menggabungkan n elemen.
StringBuilder dirancang untuk meminimalkan penyalinan ini. Ini menggunakan struktur data internal yang sederhana namun pintar untuk menghindari penyalinan sama sekali sampai akhir, ketika Anda meminta String terakhir dengan panggilan toString ():
Mendapatkan kinerja yang baik adalah salah satu alasan mengapa kami menggunakan objek yang bisa berubah. Lain adalah berbagi nyaman: dua bagian dari program Anda dapat berkomunikasi lebih nyaman dengan berbagi struktur data yang bisa berubah-ubah.
Lebih banyak dapat ditemukan di sini: https://web.mit.edu/6.005/www/fa15/classes/09-immutability/#useful_immutable_types
sumber
Objek abadi adalah objek yang tidak dapat Anda modifikasi setelah Anda membuatnya. Contoh tipikal adalah string literal.
Bahasa pemrograman AD, yang menjadi semakin populer, memiliki gagasan "kekekalan" melalui kata kunci "invarian". Lihat artikel Dr.Dobb ini tentang hal itu - http://dobbscodetalk.com/index.php?option=com_myblog&show=Invariant-Strings.html&Itemid=29 . Ini menjelaskan masalah dengan sempurna.
sumber