為什么Java的String不可變?

為什么Java的String不可變?

場景: 你在開發多線程用戶系統時,發現用戶密碼作為String傳遞后,竟被其他線程修改。這種安全隱患源于對String可變性的誤解。Java將String設計為不可變類,正是為了解決這類核心問題。

1?? 不可變性的本質:源碼級的保護

// JDK String類關鍵源碼
public final class Stringimplements java.io.Serializable, Comparable<String>, CharSequence {// 關鍵1:final修飾的字符數組private final char value[];// 關鍵2:哈希值緩存(首次計算后不再變更)private int hash; // Default to 0// 構造方法:深度復制而非直接引用public String(char value[]) {this.value = Arrays.copyOf(value, value.length);}// 沒有修改value數組的方法!
}

三大保護機制

  1. final class:禁止繼承破壞
  2. private final char[]:字符數組引用不可變
  3. 構造器Arrays.copyOf:防止外部修改原始數組

2?? 不可變性的五大核心價值

? 價值1:線程安全的天然保障
// 多線程共享用戶憑證
public class AuthService {// 不可變String天然線程安全private final String adminPassword = "S3cr3t!";public boolean login(String input) {// 無需同步鎖return adminPassword.equals(input);}
}

優勢

  • 多線程共享無需同步
  • 避免死鎖和性能損耗
? 價值2:哈希優化的關鍵基礎
// String的hashCode實現(JDK源碼)
public int hashCode() {int h = hash;if (h == 0 && value.length > 0) {char val[] = value;for (int i = 0; i < value.length; i++) {h = 31 * h + val[i];}hash = h; // 計算后緩存}return h;
}

Map性能優勢

  1. 作為HashMap鍵時,哈希值只需計算一次
  2. 相同字符串可復用哈希值(如常量池字符串)
? 價值3:字符串常量池的基石
String s1 = "Java";  // 在常量池創建
String s2 = "Java";  // 復用常量池對象
String s3 = new String("Java"); // 強制堆中創建新對象System.out.println(s1 == s2); // true (同一對象)
System.out.println(s1 == s3); // false (不同對象)

內存優化效果

場景創建對象數內存占用
100次new String("text")100100x
100次"text"字面量11x
? 價值4:安全防御的堅固盾牌
// 敏感信息傳遞
public void processPassword(String password) {// 即使惡意方法嘗試修改modifyString(password); // 無效!// password保持原值
}void modifyString(String s) {// 無法修改原始字符串s = "hacked!"; // 只改變局部引用
}

安全場景

  • 網絡傳輸參數
  • 數據庫連接憑證
  • 文件路徑驗證
? 價值5:類加載機制的安全保障
// 類加載依賴字符串
public class MyClass {static {System.loadLibrary("nativeLib"); // 依賴不可變路徑}
}

系統級影響

  • 類名、方法名等元數據使用String
  • 防止核心類加載被篡改

3?? 性能對比:不可變 vs 可變

測試場景:千萬次字符串拼接
// 不可變方案(產生大量中間對象)
String result = "";
for (int i = 0; i < 10_000_000; i++) {result += i; // 每次循環創建新String
}// 可變方案(推薦)
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10_000_000; i++) {sb.append(i);
}
String result = sb.toString();

性能測試結果

方案執行時間內存消耗對象創建數
直接拼接String超時(>60s)超高1000萬+
StringBuilder0.8s穩定1

最佳實踐

  • 少量拼接:直接用+
  • 循環/大批量:必須用StringBuilder

4?? 不可變性的實現代價與解決方案

代價:頻繁修改的性能損耗
// 反例:在循環中拼接字符串
String path = "";
for (String dir : directories) {path += "/" + dir; // 每次創建新對象!
}// 正解:使用StringBuilder
StringBuilder pathBuilder = new StringBuilder();
for (String dir : directories) {pathBuilder.append("/").append(dir);
}
String path = pathBuilder.toString();
解決方案:可變搭檔類
場景特點
StringBuilder單線程字符串操作非線程安全,高性能
StringBuffer多線程字符串操作線程安全,稍慢
char[]超高性能底層操作直接操作字符數組

5?? 現代Java的增強設計

Java 8+ 的緊湊字符串優化
// -XX:+UseCompactStrings 默認開啟
public final class String {private final byte[] value; // 不再總是char[]private final byte coder;   // 標識編碼(LATIN1/UTF16)
}

優化效果

  • 純英文字符串內存占用減半(1字節/字符)
  • 保持完全兼容的不可變性

總結:為什么不可變是終極選擇?

需求維度不可變String的解決方案可變字符串的風險
線程安全天然支持,無需同步需額外鎖機制
哈希性能一次計算,永久緩存每次需重新計算
內存效率常量池復用,減少重復相同字符串多次存儲
系統安全核心參數防篡改敏感數據可能被修改
類加載安全保證元數據完整性可能破壞類加載機制

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/90305.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/90305.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/90305.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

在Ubuntu上使用QEMU學習RISC-V程序(1)起步第一個程序

文章目錄一、 引言二、 環境準備三、編寫簡單的RISC-V程序四、 編譯步驟詳解五、使用QEMU運行程序六、程序詳解七、退出QEMU八、總結附錄&#xff1a;QEMU中通過UTRA顯示字符工作原理1、內存映射I/O原理2、add.s程序工作流程3、關鍵指令解析4、QEMU模擬的UART控制器5、為什么不…

R擬合 | 一個分布能看到三個峰,怎么擬合出這三個正態分布的參數? | 高斯混合模型 與 EM算法

1. 效果已知數據符合上圖分布&#xff0c;怎么求下圖的三個分布的參數mu, sigma&#xff0c;及每個分布的權重 lambda&#xff1f; 2. 代碼: 高斯混合模型&#xff08;Gaussian Mixture Model&#xff0c;簡稱GMM&#xff09; library(mixtools) set.seed(123) # 確保結果可重復…

Excel自動分列開票工具推薦

軟件介紹 本文介紹一款基于Excel VBA開發的自動分列開票工具&#xff0c;可高效處理客戶對賬單并生成符合要求的發票清單。 軟件功能概述 該工具能夠將客戶對賬單按照訂單號自動拆分為獨立文件&#xff0c;并生成可直接導入發票清單系統的標準化格式。 軟件特點 這是一款體…

【自用】JavaSE--Stream流

概述獲取Stream流集合的stream流集合名.stream( );collection集合List集合與Set集合都屬于Collection集合&#xff0c;因此可以直接調用stream方法獲取stream流&#xff0c;示例如下結果>map集合map集合存在鍵值對&#xff0c;因此無法使用該方法直接獲取stream流&#xff0…

【Elasticsearch】快照與恢復功能詳解

《Elasticsearch 集群》系列&#xff0c;共包含以下文章&#xff1a; 1?? 冷熱集群架構2?? 合適的鍋炒合適的菜&#xff1a;性能與成本平衡原理公式解析3?? ILM&#xff08;Index Lifecycle Management&#xff09;策略詳解4?? Elasticsearch 跨機房部署5?? 快照與恢…

技嘉z370主板開啟vtx

技嘉z370vtx應該默認就是開啟狀態&#xff0c;雖然主板開啟的vtx但是系統默認設置會導致vtx不能使用 1. 關閉hyper-V,Windows虛擬機監控程序平臺,虛擬機平臺 控制面板->程序->啟用或關閉windows功能 2.以管理員身份運行CMD bcdedit /set hypervisorlaunchtype off 3.…

Springmvc的自動解管理

中央轉發器&#xff08;DispatcherServlet&#xff09;控制器視圖解析器靜態資源訪問消息轉換器格式化靜態資源管理一、中央轉發器Xml無需配置<servlet><servlet-name>chapter2</servlet-name><servlet-class>org.springframework.web.servlet.Dispatc…

C#_定時器_解析

問題一:這里加lock是啥意思?它的原理是, 為什么可以鎖住? private readonly Timer _timer;/// <summary>/// 構造函數中初始化定時器/// </summary>public FtpTransferService(){// 初始化定時器_timer new Timer(_intervalMinutes * 60 * 1000);_timer.Elapsed…

Trae開發uni-app+Vue3+TS項目飄紅踩坑

前情 Trae IDE上線后我是第一時間去使用體驗的&#xff0c;但是因為一直排隊問題不得轉戰Cursor&#xff0c;等到Trae出付費模式的時候&#xff0c;我已經辦了Cursor的會員&#xff0c;本來是想等會員過期了再轉戰Trae的&#xff0c;但是最近Cursor開始做妖了 網上有一堆怎么…

低代碼中的統計模型是什么?有什么作用?

低代碼開發平臺中的統計模型是指通過可視化配置、拖拽操作或少量代碼即可應用的數據分析工具&#xff0c;旨在幫助技術人員及非技術人員快速實現數據描述、趨勢預測和業務決策。其核心價值在于降低數據分析門檻&#xff0c;使業務人員無需深入掌握統計原理或編程技能&#xff0…

Linux 下在線安裝啟動VNC

描述 Linux中的VNC就類似于Windows中的遠程桌面系統 本文只記錄在Cent OS 7的系統下在線安裝VNC。 安裝VNC 1、安裝VNC yum install tigervnc-server2、配置VNC的密碼 為用戶設置 VNC 密碼&#xff08;首次運行會提示輸入&#xff0c;也可以提前輸入&#xff09; vncpasswd密碼…

支持OCR和AI解釋的Web PDF閱讀器:解決大文檔閱讀難題

支持OCR和AI解釋的Web PDF閱讀器&#xff1a;解決大文檔閱讀難題一、背景&#xff1a;為什么需要這個工具&#xff1f;問題場景解決方案二、技術原理&#xff1a;如何實現這些功能&#xff1f;1、核心技術組件2、工作流程3、關鍵點三、操作指南1、環境準備2、生成Html代碼3、We…

研發過程都有哪些

產品規劃與定義 (Product Planning & Definition) 在詳細的需求調研之前&#xff0c;通常會進行市場分析、競品分析、確立產品目標和核心價值。這個階段決定了“我們要做什么”以及“為什么要做”。 系統設計與架構 (System & Architectural Design) 這是開發的“藍圖”…

舊物回收小程序系統開發——開啟綠色生活新篇章

在當今社會&#xff0c;環保已經成為全球關注的焦點話題。隨著人們生活水平的提高&#xff0c;消費能力不斷增強&#xff0c;各類物品的更新換代速度日益加快&#xff0c;大量舊物被隨意丟棄&#xff0c;不僅造成了資源的巨大浪費&#xff0c;還對環境產生了嚴重的污染。在這樣…

UE5 UI 水平框

文章目錄slot區分尺寸和對齊方式尺寸&#xff1a;自動模式尺寸&#xff1a;填充模式對齊常用設置所有按鈕大小一致&#xff0c;不受文本影響靠右排列和unity的HorizontalLayout不太一樣slot 以在水平框中放入帶文字的按鈕為例 UI如下布置 按鈕的大小受slot的尺寸、對齊和內部…

【Golang】Go語言變量

Go語言變量 文章目錄Go語言變量一、Go語言變量二、變量聲明2.1、第一種聲明方式2.2、第二種聲明方式2.3、第三種聲明方式2.4、多變量聲明2.5、打印變量占用字節一、Go語言變量 變量來源于數學&#xff0c;是計算機語言中能存儲計算結果或能表示值抽象的概念變量可以通過變量名…

Qt WebEngine Widgets的使用

一、Qt WebEngine基本概念Qt WebEngine中主要分為三個模塊&#xff1a;Qt WebEngine Widgets模塊&#xff0c;主要用于創建基于C Widgets部件的Web程序&#xff1b;Qt WebEngine模塊用來創建基于Qt Quick的Web程序&#xff1b;Qt WebEngine Core模塊用來與Chromeium交互。網頁玄…

【C++】標準模板庫(STL)—— 學習算法的利器

【C】標準模板庫&#xff08;STL&#xff09;—— 學習算法的利器學習 STL 需要注意的幾點及 STL 簡介一、什么是 STL&#xff1f;二、學習 STL 前的先修知識三、STL 常見容器特點對比四、學習 STL 的關鍵注意點五、STL 學習路線建議六、總結七、下一章 vector容器快速上手學習…

YOLO算法演進綜述:從YOLOv1到YOLOv13的技術突破與應用實踐,一文掌握YOLO家族全部算法!

引言&#xff1a;介紹目標檢測技術背景和YOLO算法的演進意義。YOLO算法發展歷程&#xff1a;使用階段劃分方式系統梳理各代YOLO的技術演進&#xff0c;包含早期奠基、效率優化、注意力機制和高階建模四個階段。YOLOv13的核心技術創新&#xff1a;詳細解析HyperACE機制、FullPAD…

快速將前端得依賴打為tar包(yarn.lock版本)并且推送至nexus私有依賴倉庫(筆記)

第一步創建js文件 文件名為downloadNpmPackage.jsprocess.env.NODE_TLS_REJECT_UNAUTHORIZED "0";const fs require("fs"); const path require("path"); const request require("request");// 設置依賴目錄 const downUrl "…