再談String

1、字符串常量池

1.1 創建對象的思考

下面是兩種創建字符串對象的代碼

public static void main1(String[] args) {String s1 = "hello";String s2 = "hello";System.out.println(s1 == s2);//trueString s3 = new String("hello");String s4 = new String("hello");System.out.println(s1 == s3);//falseSystem.out.println(s3 == s4);//false}

上述程序創建方式類似,但為什么打印結果s1 == s2的時候是true,s1 == s3打印的時候是false,s3 == s4打印的時候是false呢?

在Java中,對于1、2、3、3.14、“hello”等字面類型的常量經常頻繁使用,為了使程序運行更快,更節省內存,Java為8種基本類型和String類都提供了常量池。

"池" 是編程中的一種常見的, 重要的提升效率的方式, 我們會在未來的學習中遇到各種 "內存池", "線程池", "數 據庫連接池" .... 比如:家里給大家打生活費的方式 1. 家里經濟拮據,每月定時打生活費,有時可能會晚,最差情況下可能需要向家里張口要,速度慢 2. 家里有礦,一次性打一年的生活費放到銀行卡中,自己隨用隨取,速度非常快 方式2,就是池化技術的一種示例,錢放在卡上,隨用隨取,效率非常高。常見的池化技術比如:數據庫連接 池、線程池等。

為了節省程序存儲的空間并且提高程序的運行效率,Java種引入了:

1、Class文件常量池:每個Java源文件編譯后生成.class文件中會保存當前類中的字面常量以及符號信息。

2、運行時常量池:在.class文件被加載時候,.class文件中的常量池被加載到內存中稱之為運行時常量池,運行時常量池每個類都有一份。

3、字符常量池:其具體概念會在講解JVM時候詳細解釋。

1.2 字符串常量池

字符串常量池在Java的官方文檔中并未詳細說明,只是有一個在JVM中的StringTable類,實際上,是一個固定大小是HashTable(一種高效用來進行查找的數據結構),不同JDK版本下字符串常量池的位置以及默認大小是不同的:

1.3?字符串常量池的創建

如下代碼,創建字符串就會先在字符串常量池先進行創建:

public static void main(String[] args){String s1 = "hello";String s2 = "hello";System.out.println(s1 == s2);//true
}

那么創建過程是什么呢?下面通過畫圖進行講解:

JVM中存在棧和堆。

當執行代碼String s1 = "hello"的時候,堆中有一個StringTable類,其中是一個HashTable,在HashTable中存儲的是一些鏈表的地址。當我們String s1 = "hello"的時候,常量池中會有一個空間來指向一個鏈表,這個鏈表會再指向一個String對象,這個String對象的value會指向一個字符數組,從而存儲起來hello。?

同時,棧中開辟一塊空間存放0x11。?這就是一次將常量放入常量池的過程。

存儲字符串常量的時候,會先檢查當前的常量池中 是否存在所要存儲的常量,如果有的話,就不會再放入常量池中!

我們剛剛定義了String s2 = "hello",則先會再常量池中,尋找一下,是否有“hello”的常量,檢查發現有,則直接再在棧中開辟一塊空間給s2,但因為s2所要存儲的常量以及在常量池中了,所以s2的地址直接指向常量池中是String對象即可。

所以在打印s1==s2的時候是true。

但如果是s3的創建方式:new String("hello")。?創建結果如圖所示:

?即只要有new一個對象的發生,就一定會在堆中創建一個對象,則s4指向的地址為0x999的對象的地址,雖然也可以找到地址為0x88的hello,但s1和s3所存的地址就不一樣了,所以在打印的時候,會出現s1?== s3的結果為false。

通過上面的例子可以看出:使用常量串創建String類型對象的效率更高,而且更節省空間。

1.4 intern方法

有如下代碼:

    public static void main(String[] args) {char[] ch = {'a','b','c'};String s1 = new String(ch);String s2 = "abc";System.out.println(s2 == s1);}

通過上面內容的學習:我們知道輸出的結果一定是false。

過程如下:

char[] ch = new char[]{'a', 'b', 'c'};之后,會在堆里有一個字符數組0x87,然后ch中存儲地址0x87。

然后String s1 = new String(ch); 和上面一樣,new出了新是對象String。

執行String s2 = "abc"的時候,過程如下,將 a b c放入常量池中?。

此時s1 和 s2指向的地址并不相同,索引打印結果自然是false。

但如果在String s1 = new String(ch)的代碼之后,添加一行代碼:s1.intern(),就可以實現將s1對象的引用放入到常量池。

    public static void main(String[] args) {char[] ch = {'a','b','c'};String s1 = new String(ch);String s2 = "abc";s1.intern();//1、先檢查s1所指向的對象是否在常量池2、有則不入池,沒有則入池System.out.println(s2 == s1);}

如果加上了這行代碼,過程就會如下圖所示,結果返回true:?intern方法:

1.會先檢查調用該方法所指的對象是否在常量池中存在。

2.如果有則不入池。

3.如果沒有則入池。

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

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

相關文章

《深入淺出ProtoBuf:從環境搭建到高效數據序列化》?

ProtoBuf詳解 1、初識ProtoBuf2、安裝ProtoBuf2.1、ProtoBuf在Windows下的安裝2.2、ProtoBuf在Linux下的安裝 3、快速上手——通訊錄V1.03.1、步驟1:創建.proto文件3.2、步驟2:編譯contacts.proto文件,生成C文件3.3、步驟3:序列化…

基于PHP+Uniapp的互聯網醫院源碼:電子處方功能落地方案

隨著“互聯網醫療”政策紅利持續釋放,互聯網醫院已成為推動醫療數字化轉型的重要方向。在這一趨勢下,電子處方功能模塊作為核心環節,不僅直接關系到線上問診閉環的實現,也成為系統開發中技術難度較高、業務邏輯最為復雜的一部分。…

ARM Cortex-M (STM32)如何調試HardFault

目錄 步驟 1: 實現一個有效的 HardFault 處理程序 步驟 2: 復現 HardFault 并使用調試器分析 步驟 3: 解讀故障信息 步驟 4: 定位并修復源代碼 HardFault 是 ARM Cortex-M 處理器中的一種異常。當處理器遇到無法處理的錯誤,或者配置為處理特定類型錯誤&#xff…

基于歸納共形預測的大型視覺-語言模型中預測集的**數據驅動校準**

摘要 本研究通過分離共形預測(SCP)框架,解決了大型視覺語言模型(LVLMs)在視覺問答(VQA)任務中幻覺緩解的關鍵挑戰。雖然LVLMs在多模態推理方面表現出色,但它們的輸出常常表現出具有…

LangChain4j 搭配 Kotlin:以協程、流式交互賦能語言模型開發

Kotlin 支持 | LangChain4j Kotlin 是一種面向 JVM(及其他平臺)的靜態類型語言,能夠實現簡潔優雅的代碼,并與 Java 庫無縫互操作。 LangChain4j 利用 Kotlin 擴展和類型安全構建器來增強 Java API,為其增添特定于 Ko…

正大模型視角下的市場結構判斷邏輯

正大模型視角下的市場結構判斷邏輯 在多數交易策略中,結構識別往往先于方向判斷。以正大的數據研判風格為例,其核心邏輯是:價格行為不能孤立解讀,必須結合時間與成交效率來判斷當前結構的有效性。 例如,一個上漲過程&…

Django 入門實戰:從環境搭建到構建你的第一個 Web 應用

Django 入門實戰:從環境搭建到構建你的第一個 Web 應用 恭喜你選擇 Django 作為你學習 Python Web 開發的起點!Django 是一個強大、成熟且功能齊全的框架,非常適合構建中大型的 Web 應用程序。本篇將通過一個簡單的例子,帶你走完…

Unity 打包后 無陰影 陰影不顯示

在項目設置里面->質量 這里面顯示的是打包之后的質量 PS:注意運行質量 點擊左鍵選擇運行質量,這倆不一致就會導致,運行有陰影但是打包出來的平臺沒有陰影,原因就在這. 質量等級選擇好之后 往下滑,在這里打開陰影,如果距離過遠不顯示陰影,就增加陰影距離.

python——面向對象編程

一、編程思想 面向過程編程(典型:c語言):是一種以過程為中心的編程思想。它強調流程化、線性化、步驟化的思考方式,實現思路就是函數。 面向對象編程:強調整體性和差異性。它將任何事物看做一個統一整個&…

宿主機和容器 ping 不通域名解決方法

目錄 一、問題描述 二、宿主機解決方法 三、容器解決辦法 一、問題描述 宿主機是Ubuntu,在宿主機上 ping 不通域名:xxxx.cn,但是個人電腦能 ping 通。 同時宿主機上的啟動的k8s容器也無法ping通。 二、宿主機解決方法 ①編輯文件&#xff…

windows作業job介紹

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 前言一、作業job是什么?二、使用步驟1.代碼示例 總結 前言 提示:這里可以添加本文要記錄的大概內容: winapi網站: h…

ESG跨境電商如何為國內的跨境電商企業打開國外的市場

現在不管是國內還是國外,做電商的企業都非常的多,那么既然有這么多大電商公司,就要有為這些電商公司提供服務的公司,這就是ESG,它是專門為跨境電商服務的公司,那么這家公司的主要業務是什么呢?它…

龍虎榜——20250425

指數依然在震蕩,等待方向選擇,整體量能不搞但個股紅多綠少。 2025年4月25日龍虎榜行業方向分析 一、核心主線方向 綠色電力(政策驅動業績彈性) ? 代表標的:華銀電力(綠電運營)、西昌電力&…

大數據學習(112)-HIVE中的窗口函數

🍋🍋大數據學習🍋🍋 🔥系列專欄: 👑哲學語錄: 用力所能及,改變世界。 💖如果覺得博主的文章還不錯的話,請點贊👍收藏??留言📝支持一…

【MySQL】MySQL索引與事務

目錄 前言 1. 索引 (index) 1.1 概念 1.2 作用 1.3 使用場景 1.4 索引的相關操作 查看索引 創建索引 刪除索引 2. 索引背后的數據結構 2.1 B樹 2.2 B+樹的特點 2.3 B+樹的優勢 3. 事務 3.1 為什么使用事務 3.2 事…

python21-循環小作業

課程:B站大學 記錄python學習,直到學會基本的爬蟲,使用python搭建接口自動化測試就算學會了,在進階webui自動化,app自動化 循環語句小作業 for-in作業斐波那契 for 固定數值計算素數字符統計數字序列range 函數 水仙花…

深度學習小記(包括pytorch 還有一些神經網絡架構)

這個是用來增加深度學習的知識面或者就是記錄一些常用的命令,會不斷的更新 import torchvision.transforms as transforms toPIL transforms.ToPILImage()#可以把tensor轉換為Image類型的 imgtoPIL(img) #利用save就可以保存下來 img.save("/opt/data/private/stable_si…

Neo4j 可觀測性最佳實踐

Neo4j 介紹 Neo4j 是一款領先的圖數據庫管理系統,采用圖數據模型來表示和存儲數據。它以節點、關系和屬性的形式組織數據,節點代表實體,關系表示節點間的連接,屬性則為節點和關系附加信息。Neo4j 使用 Cypher 查詢語言&#xff0…

算法訓練營第三十天 | 動態規劃 (三)

提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔 文章目錄 一、01背包問題理論基礎(一)動態規劃五部曲確定dp數組以及下標的含義確定遞推公式初始化dp數組確定遍歷順序 二、01背包問題理論基礎&#…

玩機搞機基本常識-------小米OLED屏幕機型怎么設置為永不休眠_手機不息屏_保持亮屏功能 拒絕“燒屏” ?

前面在幫一位粉絲解決小米OLED機型在設置----鎖屏下沒有永不休眠的問題。在這里,大家要明白為什么有些小米機型有這個設置有的沒有的原因。區分OLED 屏幕和 LCD屏幕的不同。從根本上拒絕燒屏問題。 OLED 屏幕的一些優缺點💝💝💝 …