Saya ditanya dalam sebuah wawancara mengapa String tidak bisa diubah
Saya menjawab seperti ini:
Ketika kita membuat string dalam java seperti
String s1="hello";
maka objek akan dibuat dalam string pool (halo) dan s1 akan menunjuk ke halo . Sekarang jika lagi kita lakukanString s2="hello";
maka objek lain tidak akan dibuat tetapi s2 akan menunjuk kehello
karena JVM pertama akan memeriksa jika objek yang sama hadir dalam kumpulan string atau tidak. Jika tidak ada maka hanya yang baru yang dibuat tidak.
Sekarang jika java misalkan memungkinkan string bisa berubah maka jika kita mengubah s1 untuk hello world
kemudian s2 nilai juga akan hello world
jadi java String adalah kekal.
Bisakah ada yang memberi tahu saya jika jawaban saya benar atau salah ?
std::string
bisa berubah, tetapi mereka juga memiliki kumpulan string (well, lebih tepatnya, kumpulan array karakter).Jawaban:
String
tidak dapat diubah karena beberapa alasan, berikut ini ringkasannya:String
dalam koneksi jaringan, url koneksi basis data, nama pengguna / kata sandi dll. Jika itu bisa berubah, parameter ini dapat dengan mudah diubah.String
digunakan sebagai argumen untuk pemuatan kelas. Jika bisa berubah-ubah, ini bisa mengakibatkan kelas yang salah dimuat (karena objek yang bisa berubah mengubah statusnya).Yang sedang berkata, kekekalan
String
hanya berarti Anda tidak dapat mengubahnya menggunakan API publiknya. Anda sebenarnya dapat mem-bypass API normal menggunakan refleksi. Lihat jawabannya di sini .Dalam contoh Anda, jika
String
dapat diubah, pertimbangkan contoh berikut:sumber
String
dapat diubah, maka pemuat kelas akan mengambil string yang dilewati, membuat salinan, dan tidak mengubah salinannya. Ketika memikirkan masalah dengan sable yangjava.lang.String
dapat berubah , pikirkan bagaimana C ++ menyelesaikan masalah ini (karenastd::string
s dapat berubah .Pengembang Java memutuskan bahwa String tidak dapat diubah karena aspek desain, efisiensi, dan keamanan berikut .
Design Strings dibuat di area memori khusus di tumpukan java yang dikenal sebagai "kolam String Intern". Saat Anda membuat String baru (Tidak dalam kasus menggunakan konstruktor String () atau fungsi String lainnya yang secara internal menggunakan konstruktor String () untuk membuat objek String baru; konstruktor String () selalu membuat konstanta string baru di pool kecuali kita panggil variabel metode intern () ) yang dicari kolam untuk memeriksa apakah sudah ada. Jika ada, maka kembali referensi objek String yang ada. Jika String tidak dapat diubah, mengubah String dengan satu referensi akan menghasilkan nilai yang salah untuk referensi lainnya.
Menurut artikel ini di DZone:
sumber
Kami tidak dapat memastikan apa yang sebenarnya dipikirkan oleh perancang Java saat mendesain,
String
tetapi kami hanya dapat menyimpulkan alasan-alasan ini berdasarkan keuntungan yang kami dapatkan dari kekekalan tali, Beberapa di antaranya adalah1. Adanya String Constant Pool
Seperti yang dibahas dalam Mengapa String Disimpan dalam artikel String Constant Pool , setiap aplikasi membuat terlalu banyak objek string dan untuk menyelamatkan JVM dari pertama membuat banyak objek string dan kemudian mengumpulkan sampah mereka. JVM menyimpan semua objek string dalam area memori terpisah yang disebut String constant pool dan menggunakan kembali objek dari pool cache tersebut.
Setiap kali kita membuat string literal, JVM pertama kali melihat apakah literal itu sudah ada dalam kumpulan konstan atau tidak dan jika ada, referensi baru akan mulai menunjuk ke objek yang sama di SCP.
Dalam contoh di atas objek string dengan nilai
Naresh
akan bisa dibuat di SCP hanya sekali dan semua referensia
,b
,c
akan menunjuk ke objek yang sama tetapi bagaimana jika kita mencoba untuk membuat perubahana
misalnyaa.replace("a", "")
.Idealnya,
a
harus memiliki nilaiNresh
tetapib
,c
harus tetap tidak berubah karena sebagai pengguna akhir kami hanya melakukan perubahana
. Dan kita tahua
,b
,c
semua yang menunjuk objek yang sama jadi jika kita membuat perubahan dalama
, orang lain juga harus mencerminkan perubahan.Tetapi string immutability menyelamatkan kita dari skenario ini dan karena immutability objek string objek string
Naresh
tidak akan pernah berubah. Jadi, ketika kita membuat perubahan,a
bukannya mengubah objek string,Naresh
JVM membuat objek baru yang menetapkannyaa
lalu membuat perubahan pada objek itu.Jadi string pool hanya mungkin karena String tidak dapat diubah dan jika String tidak akan berubah, maka caching objek string dan menggunakannya kembali tidak akan memiliki kemungkinan karena variabel apa pun telah mengubah nilai dan merusak yang lain.
Dan itulah mengapa ditangani oleh JVM dengan sangat khusus dan telah diberikan area memori khusus.
2. Keamanan Thread
Objek disebut thread-safe ketika beberapa utas beroperasi di atasnya tetapi tidak satu pun dari mereka yang dapat merusak kondisinya dan objek memiliki status yang sama untuk setiap utas pada setiap titik waktu.
Karena kita objek yang tidak dapat diubah tidak dapat dimodifikasi oleh siapa pun setelah penciptaannya yang membuat setiap objek yang tidak dapat diubah adalah thread yang aman secara default. Kami tidak perlu menerapkan langkah-langkah keamanan ulir apa pun untuk itu seperti membuat metode yang disinkronkan.
Jadi karena objek string sifatnya yang tidak berubah dapat dibagikan oleh banyak utas dan bahkan jika ia dimanipulasi oleh banyak utas, ia tidak akan mengubah nilainya.
3. Keamanan
Di setiap aplikasi, kita perlu menyampaikan beberapa rahasia misalnya nama pengguna \ kata sandi, URL koneksi dan secara umum, semua informasi ini diteruskan sebagai objek string.
Sekarang anggaplah jika String tidak akan berubah di alam maka itu akan menyebabkan ancaman keamanan serius pada aplikasi karena nilai-nilai ini diperbolehkan untuk diubah dan jika diizinkan maka ini mungkin bisa berubah karena kode yang ditulis secara salah atau orang lain yang memiliki akses ke referensi variabel kami.
4. Memuat Kelas
Seperti yang dibahas dalam Membuat objek melalui Refleksi di Java dengan Contoh , kita bisa menggunakan
Class.forName("class_name")
metode untuk memuat kelas di memori yang lagi-lagi memanggil metode lain untuk melakukannya. Dan bahkan JVM menggunakan metode ini untuk memuat kelas.Tetapi jika Anda melihat dengan jelas semua metode ini menerima nama kelas sebagai objek string sehingga Strings digunakan dalam pemuatan kelas java dan imutabilitas memberikan keamanan yang dapat dimasuki oleh kelas yang benar
ClassLoader
.Misalkan jika String tidak akan berubah dan kami mencoba memuat
java.lang.Object
yang bisa diubahorg.theft.OurObject
di antaranya dan sekarang semua objek kami memiliki perilaku yang dapat digunakan seseorang untuk hal-hal yang tidak diinginkan.5. Cache HashCode
Jika kita akan melakukan operasi hashing apa pun pada objek apa pun, kita harus mengganti
hashCode()
metode tersebut dan mencoba menghasilkan kode hash yang akurat dengan menggunakan status objek. Jika keadaan objek semakin berubah yang berarti kode hashnya juga harus berubah.Karena String tidak dapat diubah, maka nilai yang dipegang satu objek string tidak akan pernah berubah yang berarti kode hashnya juga tidak akan berubah yang memberikan kelas String peluang untuk melakukan cache kode hash-nya selama pembuatan objek.
Ya, objek String mem-cache kode hash-nya pada saat pembuatan objek yang menjadikannya kandidat terbaik untuk hashing operasi terkait karena kode hash tidak perlu dihitung lagi yang menghemat waktu kita. Inilah sebabnya mengapa String sebagian besar digunakan sebagai
HashMap
kunci.Baca Lebih Lanjut tentang Mengapa String Tidak Berubah dan Final di Jawa .
sumber
Alasan terpenting menurut artikel ini di DZone:
Semoga ini bisa membantu Anda.
sumber
Saya membaca posting ini Mengapa String Tidak Berubah atau Final di Jawa dan menganggap bahwa berikut ini mungkin alasan paling penting:
sumber
Kamu benar.
String
dalam java menggunakan konsepString Pool
literal. Ketika string dibuat dan jika string sudah ada di kumpulan, referensi dari string yang ada akan dikembalikan, alih-alih membuat objek baru dan mengembalikan referensi. Jika string tidak dapat diubah, mengubah string dengan satu referensi akan mengarah pada nilai yang salah untuk referensi lainnya.Saya akan menambahkan satu hal lagi, karena
String
tidak dapat diubah, aman untuk multi threading dan sebuah instance String tunggal dapat dibagi di berbagai utas. Ini menghindari penggunaan sinkronisasi untuk keamanan utas, Strings secara implisitthread safe
.sumber
Kelas string
FINAL
artinya Anda tidak dapat membuat kelas apa pun untuk mewarisinya dan mengubah struktur dasar dan membuat Sting bisa berubah.Variabel instance hal lain dan metode kelas String yang disediakan adalah sedemikian rupa sehingga Anda tidak dapat mengubah
String
objek yang pernah dibuat.Alasan apa yang Anda tambahkan tidak membuat String tidak berubah sama sekali. Ini semua mengatakan bagaimana String disimpan di heap. Juga kumpulan string membuat perbedaan besar dalam kinerja
sumber
String diberikan sebagai tidak dapat diubah oleh sistem mikro Sun, karena string dapat digunakan untuk menyimpan sebagai kunci dalam koleksi peta. StringBuffer bisa berubah. Itulah alasannya, itu tidak bisa digunakan sebagai kunci dalam objek peta
sumber
Alasan paling penting dari suatu String yang dibuat tidak berubah di Jawa adalah pertimbangan Keamanan . Selanjutnya adalah Caching .
Saya percaya alasan lain yang diberikan di sini, seperti efisiensi, konkurensi, desain, dan kumpulan string mengikuti dari fakta bahwa String in dibuat abadi. Untuk misalnya. String Pool dapat dibuat karena String tidak dapat diubah dan bukan sebaliknya.
Periksa transkrip wawancara Gosling di sini
sumber
Selain jawaban yang bagus, saya ingin menambahkan beberapa poin. Seperti Strings, Array memegang referensi ke awal array jadi jika Anda membuat dua array
arr1
danarr2
melakukan sesuatu sepertiarr2 = arr1
ini akan membuat referensi yangarr2
samaarr1
karena dengan mengubah nilai pada salah satu dari mereka akan menghasilkan perubahan yang lain misalnyaTidak hanya itu akan menyebabkan bug dalam kode itu juga dapat (dan akan) dieksploitasi oleh pengguna jahat. Misalkan jika Anda memiliki sistem yang mengubah kata sandi admin. Pengguna harus terlebih dahulu memasukkan
newPassword
dan kemudianoldPassword
jikaoldPassword
samaadminPass
dengan program mengganti kata sandiadminPass = newPassword
. katakanlah kata sandi baru memiliki referensi yang sama dengan kata sandi admin sehingga programmer yang buruk dapat membuattemp
variabel untuk menahan kata sandi admin sebelum pengguna memasukkan data jikaoldPassword
sama dengantemp
itu mengubah kata sandi sebaliknyaadminPass = temp
. Seseorang yang mengetahui bahwa dengan mudah dapat memasukkan kata sandi baru dan tidak pernah memasukkan kata sandi lama dan abracadabra ia memiliki akses admin. Hal lain yang saya tidak mengerti ketika belajar tentang Strings mengapa JVM tidak membuat string baru untuk setiap objek dan memiliki tempat yang unik dalam memori untuk itu dan Anda bisa melakukannya menggunakannew String("str");
Alasan Anda tidak ingin selalu menggunakannew
adalah karena ini tidak efisien dalam memori dan lebih lambat dalam banyak kasus, baca lebih lanjut .sumber
Jika
HELLO
adalah Anda String maka Anda tidak dapat mengubahHELLO
keHILLO
. Properti ini disebut properti kekekalan.Anda dapat memiliki beberapa variabel String penunjuk ke titik String HELLO.
Tetapi jika HELLO adalah char Array maka Anda dapat mengubah HELLO menjadi HILLO. Misalnya,
Menjawab:
Bahasa pemrograman memiliki variabel data yang tidak berubah sehingga dapat digunakan sebagai kunci dalam pasangan nilai. Variabel string digunakan sebagai kunci / indeks, sehingga tidak dapat diubah .
sumber
Dari
Security
sudut pandang kita dapat menggunakan contoh praktis ini:sumber