農林漁牧網

您現在的位置是:首頁 > 林業

為什麼 String 在 Java 中是不可變的?

2022-06-02由 黑馬程式設計師西安中心 發表于 林業

string類為什麼被設計不可變

為什麼 String 在 Java 中是 final 的。

字串在 Java 中是不可變的,因為 String 物件快取在 String 池中。由於快取的字串在多個客戶之間共享,因此始終存在風險,其中一個客戶的操作會影響所有其他客戶。例如,如果一段程式碼將 String “Test” 的值更改為 “TEST”,則所有其他客戶也將看到該值。由於 String 物件的快取效能是很重要的一方面,因此透過使 String 類不可變來避免這種風險。

同時,String 是 final 的,因此沒有人可以透過擴充套件和覆蓋行為來破壞 String 類的不變性、快取、雜湊值的計算等。String 類不可變的另一個原因可能是由於 HashMap。

由於把字串作為 HashMap 鍵很受歡迎。對於鍵值來說,重要的是它們是不可變的,以便用它們檢索儲存在 HashMap 中的值物件。由於 HashMap 的工作原理是雜湊,因此需要具有相同的值才能正常執行。如果在插入後修改了 String 的內容,可變的 String將在插入和檢索時生成兩個不同的雜湊碼,可能會丟失 Map 中的值物件。

如果你是印度板球迷,你可能能夠與我的下一句話聯絡起來。字串是Java的 VVS Laxman,即非常特殊的類。我還沒有看到一個沒有使用 String 編寫的 Java 程式。這就是為什麼對 String 的充分理解對於 Java 開發人員來說非常重要。

String 作為資料型別,傳輸物件和中間人角色的重要性和流行性也使這個問題在 Java 面試中很常見。

為什麼 String 在 Java 中是不可變的是 Java 中最常被問到的字串訪問問題之一,它首先討論了什麼是 String,Java 中的 String 如何與 C 和 C++ 中的 String 不同,然後轉向在Java中什麼是不可變物件,不可變物件有什麼好處,為什麼要使用它們以及應該使用哪些場景。這個問題有時也會問:“為什麼 String 在 Java 中是 final 的”。在類似的說明中,如果你正在準備Java 面試,我建議你看看Java程式設計面試公開書,這是高階和中級Java程式設計師的優秀資源。它包含來自所有重要 Java 主題的問題,包括多執行緒,集合,GC,JVM內部以及 Spring和 Hibernate 框架等。

正如我所說,這個問題可能有很多可能的答案,而 String 類的唯一設計者可以放心地回答它。我在 Joshua Bloch 的 Effective Java 書中期待一些線索,但他也沒有提到它。我認為以下幾點解釋了為什麼 String 類在 Java 中是不可變的或 final 的:

1)想象字串池沒有使字串不可變,它根本不可能,因為在字串池的情況下,一個字串物件/文字,例如 “Test” 已被許多參考變數引用,因此如果其中任何一個更改了值,其他引數將自動受到影響,即假設

String A=“Test”;

String B=“Test”;

現在字串 B 呼叫 “Test”。toUpperCase(), 將同一個物件改為“TEST”,所以 A 也是 “TEST”,這不是期望的結果。

下圖顯示瞭如何在堆記憶體和字串池中建立字串。

為什麼 String 在 Java 中是不可變的?

2)字串已被廣泛用作許多 Java 類的引數,例如,為了開啟網路連線,你可以將主機名和埠號作為字串傳遞,你可以將資料庫 URL 作為字串傳遞, 以開啟資料庫連線,你可以透過將檔名作為引數傳遞給 File I/O 類來開啟 Java 中的任何檔案。如果 String 不是不可變得,這將導致嚴重的安全威脅,我的意思是有人可以訪問他有權授權的任何檔案,然後可以故意或意外地更改檔名並獲得對該檔案的訪問許可權。由於不變性,你無需擔心這種威脅。這個原因也說明了,為什麼 String 在 Java 中是最終的,透過使 java。lang。String final,Java設計者確保沒有人覆蓋 String 類的任何行為。

3)由於 String 是不可變的,它可以安全地共享許多執行緒,這對於多執行緒程式設計非常重要。 並且避免了 Java 中的同步問題,不變性也使得String 例項在 Java 中是執行緒安全的,這意味著你不需要從外部同步 String 操作。關於 String 的另一個要點是由擷取字串 SubString 引起的記憶體洩漏,這不是與執行緒相關的問題,但也是需要注意的。

4)為什麼 String 在 Java 中是不可變的另一個原因是允許 String 快取其雜湊碼,Java 中的不可變 String 快取其雜湊碼,並且不會在每次呼叫 String 的 hashcode 方法時重新計算,這使得它在 Java 中的 HashMap 中使用的 HashMap 鍵非常快。簡而言之,因為 String 是不可變的,所以沒有人可以在建立後更改其內容,這保證了 String 的 hashCode 在多次呼叫時是相同的。

5)String 不可變的絕對最重要的原因是它被類載入機制使用,因此具有深刻和基本的安全考慮。如果 String 是可變的,載入“java。io。Writer” 的請求可能已被更改為載入 “mil。vogoon。DiskErasingWriter”。 安全性和字串池是使字串不可變的主要原因。順便說一句,上面的理由很好回答另一個Java面試問題: “為什麼String在Java中是最終的”。要想是不可變的,你必須是最終的,這樣你的子類不會破壞不變性。你怎麼看?