Đây là một bài viết hay nêu ra hai lý do đã được đề cập trong các câu trả lời trên:
- Bảo mật : hệ thống có thể phân phát các bit nhạy cảm của thông tin chỉ đọc mà không lo chúng bị thay đổi
- Hiệu suất : dữ liệu bất biến rất hữu ích trong việc làm cho mọi thứ an toàn theo luồng.
Và đây có lẽ là bình luận chi tiết nhất trong bài viết đó. Nó phải làm với nhóm chuỗi trong Java và các vấn đề bảo mật. Đó là về cách quyết định những gì đi vào nhóm chuỗi. Giả sử cả hai chuỗi bằng nhau nếu chuỗi ký tự của chúng giống nhau, thì chúng ta có một điều kiện cuộc đua về việc ai đến đó trước và cùng với đó là các vấn đề bảo mật. Nếu không, nhóm chuỗi sẽ chứa các chuỗi dư thừa do đó làm mất lợi thế của việc có nó ở vị trí đầu tiên. Chỉ cần đọc nó ra cho chính mình, sẽ ya?
Chuỗi mở rộng sẽ chơi tàn phá với bằng và thực tập. JavaDoc nói bằng:
So sánh chuỗi này với đối tượng được chỉ định. Kết quả là đúng khi và chỉ khi đối số không phải là null và là đối tượng Chuỗi đại diện cho cùng một chuỗi ký tự với đối tượng này.
Giả sử java.lang.String
không phải là cuối cùng, a SafeString
có thể bằng a String
, và ngược lại; bởi vì họ đại diện cho cùng một chuỗi các ký tự.
Điều gì sẽ xảy ra nếu bạn áp dụng intern
cho một SafeString
- sẽ SafeString
đi vào nhóm chuỗi của JVM? Và ClassLoader
tất cả các đối tượng mà các SafeString
tham chiếu được tổ chức sau đó sẽ bị khóa tại chỗ trong suốt vòng đời của JVM. Bạn sẽ nhận được một điều kiện cuộc đua về việc ai có thể là người đầu tiên thực hiện một chuỗi các ký tự - có thể bạn SafeString
sẽ giành chiến thắng, có thể là một String
hoặc có thể được SafeString
tải bởi một trình nạp lớp khác (do đó là một lớp khác).
Nếu bạn giành chiến thắng trong cuộc đua vào bể bơi, đây sẽ là một người độc thân thực sự và mọi người có thể truy cập vào toàn bộ môi trường của bạn (hộp cát) thông qua sự phản chiếu và secretKey.intern().getClass().getClassLoader()
.
Hoặc JVM có thể chặn lỗ này bằng cách đảm bảo rằng chỉ các đối tượng Chuỗi cụ thể (và không có lớp con) nào được thêm vào nhóm.
Nếu bằng được thực hiện sao cho SafeString
! = String
Thì SafeString.intern
! = String.intern
, Và SafeString
sẽ phải được thêm vào nhóm. Hồ bơi sau đó sẽ trở thành một bể <Class, String>
thay vì <String>
và tất cả những gì bạn cần để vào bể sẽ là một trình nạp lớp mới.