Ini adalah artikel yang bagus yang menguraikan dua alasan yang telah disebutkan pada jawaban di atas:
- Keamanan : sistem dapat membagikan bit sensitif informasi hanya baca tanpa khawatir mereka akan diubah
- Performa : data yang tidak dapat diubah sangat berguna dalam membuat hal-hal yang aman.
Dan ini mungkin komentar paling detail dalam artikel itu. Ini ada hubungannya dengan kumpulan string di Jawa dan masalah keamanan. Ini tentang bagaimana memutuskan apa yang masuk ke kolam string. Dengan asumsi kedua string sama jika urutan karakter mereka sama, maka kita memiliki kondisi balapan tentang siapa yang sampai di sana terlebih dahulu dan bersamaan dengan itu masalah keamanan. Jika tidak, maka kumpulan string akan berisi string yang berlebihan sehingga kehilangan keuntungan dari memilikinya di tempat pertama. Bacakan saja sendiri, ya?
Extending String akan memainkan malapetaka dengan equals dan intern. JavaDoc mengatakan equals:
Membandingkan string ini dengan objek yang ditentukan. Hasilnya benar jika dan hanya jika argumennya tidak nol dan merupakan objek String yang mewakili urutan karakter yang sama dengan objek ini.
Dengan asumsi java.lang.Stringitu belum final, a SafeStringbisa sama dengan String, dan sebaliknya; karena mereka mewakili urutan karakter yang sama.
Apa yang akan terjadi jika Anda melamar internke SafeString- apakah SafeStringmasuk ke kumpulan string JVM? The ClassLoaderdan semua objek yang SafeStringreferensi diadakan untuk kemudian akan mendapatkan terkunci di tempat untuk seumur hidup dari JVM. Anda akan mendapatkan kondisi balapan tentang siapa yang bisa menjadi orang pertama yang magang serangkaian karakter - mungkin Anda SafeStringakan menang, mungkin a String, atau mungkin SafeStringdimuat oleh classloader yang berbeda (dengan demikian kelas yang berbeda).
Jika Anda memenangkan perlombaan ke kolam renang, ini akan menjadi singleton sejati dan orang-orang dapat mengakses seluruh lingkungan Anda (kotak pasir) melalui refleksi dan secretKey.intern().getClass().getClassLoader().
Atau JVM dapat memblokir lubang ini dengan memastikan bahwa hanya objek String beton (dan tidak ada subkelas) yang ditambahkan ke kumpulan.
Jika persamaan diterapkan sedemikian rupa SafeString! = StringMaka SafeString.intern! = String.intern, Dan SafeStringharus ditambahkan ke kumpulan. Kolam kemudian akan menjadi kolam <Class, String>bukan <String>dan semua yang Anda butuhkan untuk memasuki kolam akan menjadi classloader segar.