1. Pengantar Kategori Immutable
Kelas Immutable: Apa yang disebut kelas immutable berarti bahwa setelah instance kelas ini dibuat, nilai variabel anggotanya tidak dapat diubah. Misalnya, banyak kelas abadi yang datang dengan JDK: Interger, Long and String, dll.
Kelas Variabel: Dibandingkan dengan kelas yang tidak dapat diubah, kelas yang dapat berubah dapat mengubah nilai variabel anggota mereka setelah membuat instance. Sebagian besar kelas yang dibuat dalam pengembangan milik kelas yang dapat berubah.
2. Keuntungan dari kelas immutable
Setelah berbicara tentang perbedaan antara kelas yang dapat berubah dan kelas yang tidak dapat diubah, kita perlu lebih memahami mengapa ada kelas yang tidak dapat diubah? Manfaat apa yang dibawa fitur seperti itu ke Java?
1. Keamanan utas
Objek yang tidak dapat diubah aman dan dapat dibagikan di antara utas. Tidak perlu menggunakan mekanisme khusus untuk memastikan masalah sinkronisasi, karena nilai objek tidak dapat diubah. Ini dapat mengurangi kemungkinan kesalahan bersamaan, karena tidak perlu menggunakan beberapa mekanisme kunci untuk memastikan masalah konsistensi memori, yang juga mengurangi overhead sinkronisasi.
2. Mudah dibangun, digunakan, dan diuji
3 ....
Metode Desain Kelas Immutable
Untuk kelas yang tidak dapat diubah, saya secara pribadi merangkum prinsip -prinsip berikut:
1. Tambahkan pengubah akhir ke kelas untuk memastikan bahwa kelas tidak diwarisi.
Jika suatu kelas dapat diwariskan, itu akan menghancurkan mekanisme kekekalan kelas, selama kelas warisan mengesampingkan metode kelas induk dan kelas warisan dapat mengubah nilai variabel anggota, maka setelah kelas anak muncul sebagai kelas induk, tidak dapat dijamin apakah kelas saat ini dapat berubah.
2. Pastikan bahwa semua variabel anggota harus merupakan modifikasi pribadi dan akhir ditambahkan
Dengan cara ini memastikan bahwa variabel anggota tidak dapat diubah. Tetapi tidak cukup untuk melakukan ini, karena jika itu adalah variabel anggota objek, dimungkinkan untuk mengubah nilainya secara eksternal. Jadi poin keempat menebus kekurangan ini.
3. Tidak ada metode yang disediakan untuk mengubah variabel anggota, termasuk setter
Hindari mengubah nilai variabel anggota melalui antarmuka lain dan menghancurkan fitur yang tidak dapat diubah.
4. Inisialisasi semua anggota melalui konstruktor dan lakukan salinan yang dalam (salinan dalam)
Jika objek yang dilewati oleh konstruktor secara langsung ditugaskan ke variabel anggota, masih dapat diubah dengan memodifikasi objek yang masuk, yang akan menyebabkan nilai variabel internal diubah. Misalnya:
kelas akhir publik immutableDemo {private final int [] myArray; ImmutableDeMo publik (int [] array) {this.myArray = array; // salah } }Metode ini tidak dapat menjamin kekekalan. MyArray dan array menunjuk ke alamat memori yang sama. Pengguna dapat mengubah nilai di dalam myArray dengan memodifikasi nilai objek array di luar ImmutableDemo.
Untuk memastikan bahwa nilai internal tidak dimodifikasi, salinan kedalaman dapat digunakan untuk membuat memori baru untuk menyimpan nilai yang masuk. Cara yang benar untuk melakukannya:
kelas akhir publik myimmutabledemo {private final int [] myArray; public myimmutabledemo (int [] array) {this.myArray = array.clone (); }}5. Dalam metode Getter, jangan mengembalikan objek itu sendiri secara langsung, tetapi mengkloning objek dan mengembalikan salinan objek.
Pendekatan ini juga mencegah kebocoran objek dan mencegah operasi langsung variabel anggota setelah mendapatkan objek anggota yang dapat berubah secara internal melalui getters, menghasilkan perubahan dalam variabel anggota.
Iv. Ketidakmampuan objek string
Objek string tidak dapat diubah setelah pembuatan memori. Penciptaan benda -benda abadi umumnya memenuhi 5 prinsip di atas. Mari kita lihat bagaimana kode string diimplementasikan.
Public Final Class StringImplements java.io.serializable, sebanding <string>, charsequence {/** nilainya digunakan untuk penyimpanan karakter. */Nilai arang akhir pribadi [];/** Offset adalah indeks pertama dari penyimpanan yang digunakan. */private final int offset;/** Hitungan adalah jumlah karakter dalam string. */count final int private;/** cache kode hash untuk string*/private int hash; // default ke 0..public string (nilai char []) {this.value = arrays.copyof (value, value.length); // Operasi salinan yang dalam} ... char publik [] tochararray () {// tidak dapat menggunakan arrays.copyof karena kelas inisialisasi kelas menghasilkan hasil [] = arang baru [value.length]; System.arraycopy (nilai, 0, hasil, 0, value.length); hasil pengembalian;} ...}Seperti yang ditunjukkan pada kode di atas, detail desain berikut dapat diamati:
1. Kelas string dimodifikasi dengan final dan tidak dapat diwariskan
2. Semua anggota string ditetapkan sebagai variabel pribadi
3. Setter nilai tidak ada
4. Dan atur nilai dan offset ke final.
5. Saat melewati nilai array variabel [], salin alih -alih menyalin nilai [] langsung ke variabel internal.
6. Saat mendapatkan nilai, itu tidak secara langsung mengembalikan referensi objek, tetapi mengembalikan salinan objek.
Ini konsisten dengan karakteristik tipe invarian yang dirangkum di atas, dan juga memastikan bahwa tipe string adalah kelas yang tidak dapat diubah.
5. Keuntungan dan Kekurangan Ketidakmampuan Objek String
Dari analisis bagian sebelumnya, data string tidak dapat diubah, jadi apa manfaat dari pengaturan fitur seperti itu? Saya merangkumnya sebagai berikut:
1. Persyaratan untuk kumpulan konstan string.
Pool string konstan dapat menggunakan kembali beberapa konstanta karakter di kolam konstan, menghindari menciptakan kembali objek yang sama setiap saat dan menghemat ruang penyimpanan. Tetapi jika string bervariasi, string konten yang sama juga menunjuk ke ruang memori yang sama dari kumpulan konstan. Ketika suatu variabel mengubah nilai dari memori itu, nilai -nilai lain yang dilalui juga akan berubah. Oleh karena itu, itu tidak sesuai dengan niat asli dari desain kolam konstan.
2. Pertimbangan Keselamatan Utas.
Contoh string yang sama dapat dibagikan oleh beberapa utas. Dengan cara ini, tidak perlu menggunakan sinkronisasi karena masalah keamanan utas. String aman-utas.
3. Loader kelas perlu menggunakan string, dan kekekalan memberikan keamanan sehingga kelas yang benar dimuat. Misalnya, jika Anda ingin memuat kelas java.sql.connection dan nilai ini diubah menjadi myhacked.connection, itu akan menyebabkan kerusakan yang tidak diketahui pada database Anda.
4. Dukung pemetaan dan caching hash.
Karena string tidak dapat diubah, kode hash di -cache saat dibuat dan tidak perlu dihitung ulang. Ini membuat string sangat cocok sebagai kunci dalam peta, dan kecepatan pemrosesan string lebih cepat daripada objek kunci lainnya. Inilah sebabnya kunci dalam hashmap sering menggunakan string.
kekurangan:
1. Jika ada kebutuhan untuk mengubah nilai objek string, sejumlah besar objek string akan dibuat.
6. Apakah objek string benar -benar tidak berubah?
Meskipun objek string menetapkan nilai ke final, ia juga memastikan bahwa variabel anggotanya tidak dapat diubah melalui berbagai mekanisme. Namun, itu masih dapat diubah melalui mekanisme refleksi. Misalnya:
// Buat string "Hello World" dan tetapkan ke referensi SString S = "Hello World"; System.out.println ("s =" + s); // halo dunia // Dapatkan bidang nilai di bidang kelas string valuefieldofString = string.class.getDeclaredfield ("value"); // Ubah izin akses dari nilai atribut nilai valuefieldofstring.setAccessible (true); // dapatkan nilai atribut nilai pada s objek char [] valueel (charoel) valuField. direferensikan oleh nilai = '_'; System.out.println ("s =" + s); // hello_worldHasil cetak adalah:
s = hello worlds = hello_world
Ditemukan bahwa nilai string telah berubah. Dengan kata lain, apa yang disebut objek "abadi" dapat dimodifikasi melalui refleksi.
Meringkaskan
Kelas yang tidak dapat diubah adalah nilai traversal anggota yang tidak dapat diubah setelah instance dibuat. Fitur ini memungkinkan kelas-kelas yang tidak dapat diabadikan untuk menyediakan fitur yang aman dari benang tetapi juga membawa overhead pembuatan objek. Setiap perubahan atribut adalah menciptakan kembali objek baru. JDK juga menyediakan banyak kelas abadi seperti integer, ganda, string, dll. Karakteristik string yang tidak dapat diubah terutama untuk memenuhi kebutuhan pengumpulan konstan, keamanan utas, dan pemuatan kelas. Penggunaan kelas immutable yang rasional dapat membawa manfaat besar.
Di atas adalah mekanisme yang tidak dapat diubah dari Java (Immutable) dan kekekalan string (disarankan) yang diperkenalkan kepada Anda oleh editor. Saya harap ini akan membantu Anda. Jika Anda memiliki pertanyaan, silakan tinggalkan saya pesan dan editor akan membalas Anda tepat waktu. Terima kasih banyak atas dukungan Anda ke situs web Wulin.com!