【JVM】對String::intern()方法深入詳解(JDK7及以上)

文章目錄

  • 1、什么是intern?
  • 2、經典例題解釋
    • 例1
    • 例2
    • 例3

1、什么是intern?

String::intern()是一個本地方法,它的作用是如果字符串常量池中已經包含一個等于此String對象的字符串,則返回代表池中這個字符串的String對象的引用;否則,會將此String對象包含的字符串添加到常量池中,并且返回此String對象的引用。----書上描述

已經包含。。。可能不太好理解。我畫圖解釋
在這里插入圖片描述
方法的執行順序肯定是從下向上依次執行的。
String s1 = “11”; 先去字符串常量池中查看是否已經存在“11”,如果存在則直接返回"11"的地址,如果不存在則會在字符串常量池中創建“11”,然后返回創建好的“11”的地址。因為之前未創建過,所以該指令會先去字符串常量池中創建“11”,然后返回11的地址 501
String s2 = new String(“11”); 也是先去字符串常量池中查看是否已經存在“11”,如果有就在堆中創建對象,存的是字符串常量池中“11”的地址501,最后,將堆中對象的地址601返回給S2 。
String s3 = s2.intern(); intern方法會從字符串常量池中,查詢當前s2字符串"11"是否存在,若不存在就會在字符串常量池中創建字符串"11"的實例, 由于s1已經在字符串常量池中已經創建了“11”,s2.intern()則返回501。

System.out.println(s1==s2);
System.out.println(s1==s3);false
true

s1==s2 返回false是因為s1指向的是字符串常量池中的"11"對象(501),而s2指向的是堆中存儲了"11"的地址的對象(601)
s1==s3 返回true 是因為s3和s1都指向的是字符串常量池中的"11"。

對String srt = new String(“str”)與 str1 = ”str“的區別不了解的話可以看篇文章

2、經典例題解釋

例1

//1
String s = new String("1");
//2
s.intern();//調用此方法之前,字符串常量池中已經存在了"1".
//3
String s2 = "1";
//4
System.out.println(s==s2);
  • 執行1,會創建兩個對像,在字符串常量池中創建一個”1“,在堆中創建一個String對象,并存儲“1”在字符串常量池中的的地址。
  • 執行2,調用此方法之前,字符串常量池中已經存在了"1",所以此指令什么都沒做,此時s指向堆中的對象。
  • 執行3,由于字符串常量池中已經存在了“1”,所以不需要再創建,返回“1”的地址,s2指向字符串常量池中的”1“。
  • 執行4,由于s指向堆中對象,s2指向字符串常量池中的對象,所以打印結果是false。

這是比較簡單的例子
下面上強度了!!!!!!

例2

		//1String s3 = new String("1")+new String("1");//2s3.intern();//3String s4 = "11";//4System.out.println(s3==s4);
  • 執行1,會在堆中創建兩個存儲字符串”1“的地址的對象和一個字面量為”11“的String對象,在字符串常量池中創建一個”1“字符串實例。
    在編譯期間,在創建String對象之前,會先創建一個StringBuilder對象,后面每次在堆中創建完一個String對象,會對該字符串執行LDC指令,LDC指令會先到字符串常量池中查找是否存在對應字符串實例的引用,如果有的話,那么直接返回這個字符串實例的地址給堆中的new的String對象,如果沒有的話,會創建一個字符串實例,然后將其添加到字符串常量池中,之后再返回這個字符串實例對象的地址給堆中創建的對象。完成String對象初始化后,都會執行StringBuilder::append()方法,將該字符串拼接到StringBuilder對象里。當都拼接完,會執行StringBuilder::toString()方法,返回一個在堆中新new的String對象,value為"11"。
    可以通過編譯后的字節碼文件清晰的觀察整個過程:
    在這里插入圖片描述
    標注的都是剛才介紹的行為。

  • 執行2,由于toString()方法只在堆中創建了一個”存儲11"的String對象,并沒有在字符串常量池中創建"11"字符串實例。按之前的說法intern應該去字符串常量池中創建字符串”11“的實例,但是在JDK7中,并沒有在字符串常量池中創建字符串"11"的實例,由于堆中已經存在了"11"這個String對象,那么為了節省空間,會在字符串常量池中申請一塊空間,存放這個String對象的地址,并返回存放的地址,也就是堆中存儲"11"的String對象的地址。

  • 執行3,會去字符串常量池中查找是否存在"11",因為第二行已經在字符串常量池中,創建了存儲堆中存儲"11"的String對象的地址的空間,則直接返回空間里面存儲的堆中String對象的地址,所以s4也指向了堆中存儲"11"的String對象。

  • 由于s3和s4都指向堆中同一個對象,所以打印結果為true。
    如圖所示:
    在這里插入圖片描述
    通過debug,可以看到兩個句柄指向的地址是一樣的:
    在這里插入圖片描述
    打印結果:
    在這里插入圖片描述

例3

		//1String s3 = new String("1")+new String("1");//2String s4 = "11";//3s3.intern();//4System.out.println(s3==s4);
  • 第一行執行結果與例2的第一行執行結果一致。
  • 執行2,由于字符串常量池中,還沒有"11",則向字符串常量池中創建字符串"11"的實例,并返回實例的地址。
  • 執行3,由于字符串常量池中已經存在"11",則不需要再創建,返回實例的地址,但由于沒有賦值操作,所以該行代碼沒有什么作用。
  • 此時,s3指向堆中存儲了“11”的String對象,而s4指向的是字符串常量池中字符串為"11"的實例,所以指向的地址不同打印結果為false
    通過debug可以看到兩個句柄指向的地址是不同的:
    在這里插入圖片描述
    打印結果:
    在這里插入圖片描述

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

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

相關文章

Java開源項目mall學習筆記(1)——項目初始化

一、學習聲明與項目介紹 該筆記是記錄學習開源項目mall過程的文檔筆記,完全原創,轉載請聲明。同時也對開源項目的作者表示感謝! mall: 🔥 mall項目是一套基于 SpringBoot Vue uni-app 實現的電商系統,包括前臺商城項…

編譯鴻蒙codelabs安裝時報錯

學習鴻蒙ArkTS時編譯codelabs樣例代碼,發現編譯完成報錯。目前鴻蒙的資料比較少,且官方文檔路徑很深,遂記錄下來,以資來者。 error: failed to start ability. Error while Launching activity修改module.json5中的exported為tru…

ArcGIS 利用cartogram插件制作變形地圖

成果圖 注:本圖數據并不完全對,只做為測試用例 操作 首先需要下載一個插件cartogram 下載地址在這里 https://www.arcgis.com/home/item.html?idd348614c97264ae19b0311019a5f2276 下載完畢之后解壓將Cartograms\HelpFiles下的所有文件復制到ArcGIS…

ffmpeg的使用

1、ffmpeg的安裝 # 安裝wget yum -y install wget # 安裝ffmpeg壓縮包 wget --no-check-certificate https://www.johnvansickle.com/ffmpeg/old-releases/ffmpeg-4.0.3-64bit-static.tar.xz # 解壓 tar -xJf ffmpeg-4.0.3-64bit-static.tar.xz # 進入目錄 cd ffmpeg-4.0.3-64…

【Git】(二)分支

1、創建分支 已存在主分支master,現在需要創建v1.0的版本,一般直接在web頁面操作。 v1.0分支,基線master,稱為項目分支。 假如,v1.0項目存在兩個項目成員sunriver2000和snow,一般還會再針對個人創建個人…

nodejs+vue+elementui學生檔案信息管理系統_06bg9

利用計算機網絡的便利,開發一套基于nodejs的大學生信息管理系統,將會給人們的生活帶來更多的便利,而且在經濟效益上,也會有很大的便利!這可以節省大量的時間和金錢。學生信息管理系統是學校不可缺少的一個環節,其內容直…

說一下什么是tcp的2MSL,為什么客戶端在 TIME-WAIT 狀態必須等待 2MSL 的時間?

1.TCP之2MSL 1.1 MSL MSL:Maximum Segment Lifetime報文段最大生存時間,它是任何報文段被丟棄前在網絡內的最長時間 1.2為什么存在MSL TCP報文段以IP數據報在網絡內傳輸,而IP數據報則有限制其生存時間的TTL字段,并且TTL的限制是基于跳數 1.3…

[高光譜]PyTorch使用CNN對高光譜圖像進行分類

項目原地址: Hyperspectral-Classificationhttps://github.com/eecn/Hyperspectral-ClassificationDataLoader講解: [高光譜]使用PyTorch的dataloader加載高光譜數據https://blog.csdn.net/weixin_37878740/article/details/130929358 一、模型加載 在…

使用JMeter創建數據庫測試

好吧!我一直覺得我不聰明,所以,我用最詳細,最明了的方式來書寫這個文章。我相信,我能明白的,你們一定能明白。 我的環境:MySQL:mysql-essential-5.1.51-win32 jdbc驅動:…

mysql 03.查詢(重點)

先準備測試數據,代碼如下: -- 創建數據庫 DROP DATABASE IF EXISTS mydb; CREATE DATABASE mydb; USE mydb;-- 創建student表 CREATE TABLE student (sid CHAR(6),sname VARCHAR(50),age INT,gender VARCHAR(50) DEFAULT male );-- 向student表插入數據…

PHP 公交公司充電樁管理系統mysql數據庫web結構apache計算機軟件工程網頁wamp

一、源碼特點 PHP 公交公司充電樁管理系統是一套完善的web設計系統,對理解php編程開發語言有幫助,系統具有完整的源代碼和數據庫,系統主要采用B/S模式開發。 源碼下載 https://download.csdn.net/download/qq_41221322/88220946 論文下…

【面試問題】當前系統查詢接口需要去另外2個系統庫中實時查詢返回結果拼接優化思路

文章目錄 場景描述優化思路分享資源 場景描述 接口需要從系統1查詢數據,查出的每條數據需要從另一個系統2中再去查詢某些字段, 比如:從系統1中查出100條數據,每條數據需要去系統2中再去查詢出行數據,可能系統1一條數…

socks5 保障網絡安全與爬蟲需求的完美融合

Socks5代理:跨足網絡安全和爬蟲領域的全能選手 Socks5代理作為一種通用的網絡協議,為多種應用場景提供了強大的代理能力。它不僅支持TCP和UDP的數據傳輸,還具備更高級的安全特性,如用戶身份驗證和加密通信。在網絡安全中&#xf…

蘋果手機批量刪除聯系人的2個方法,請查收!

【想要清理通訊錄里的“僵尸號”,但是突然發現手機不能批量刪除。一個一個刪除太麻煩了,有什么辦法可以一次性多刪幾個人嗎?】 小編想問問果粉們平時都是怎么刪除聯系人的?特別是要刪除多個聯系人的時候,大家還是選擇…

matlab保存圖片

僅作為記錄,大佬請跳過。 文章目錄 用界面中的“另存為”用saveas 用界面中的“另存為” 即可。 參考 感謝大佬博主文章:傳送門 用saveas 必須在編輯器中的plot之后用saveas(也就是不能在命令行中單獨使用——比如在編輯器中plot&#xf…

神經網絡基礎-神經網絡補充概念-46-指數加權平均的偏差修正

由來 指數加權平均(Exponential Moving Average,EMA)在初始時可能會受到偏差的影響,特別是在數據量較小時,EMA的值可能會與實際數據有較大的偏差。為了修正這種偏差,可以使用偏差修正方法,通常…

基于平臺的城市排水泵站管理系統設計

安科瑞 耿敏花 近年來我國城市內澇災害頻發,造成人員傷亡以及經濟損失嚴重,嚴重威脅著城市的安全。數據顯示,2015-2018年我國平均每年受淹或發生內澇城市的數量約占我國城市數量的1/5;人民生命財產也損失嚴重,據統計&a…

基于YOLOv5n/s/m不同參數量級模型開發構建茶葉嫩芽檢測識別模型,使用pruning剪枝技術來對模型進行輕量化處理,探索不同剪枝水平下模型性能影響【續】

這里主要是前一篇博文的后續內容,簡單回顧一下:本文選取了n/s/m三款不同量級的模型來依次構建訓練模型,所有的參數保持同樣的設置,之后探索在不同剪枝處理操作下的性能影響。 在上一篇博文中保持30的剪枝程度得到的效果還是比較理…

C++ 學習系列3 -- 函數壓棧與出棧

在C中,函數壓棧(函數調用)和出棧(函數返回)是函數調用過程中的兩個關鍵步驟。下面將逐步解釋這兩個過程: 一 函數壓棧與出棧過程簡介 函數壓棧(函數調用)的過程如下: …

2020年3月全國計算機等級考試真題(C語言二級)

2020年3月全國計算機等級考試真題(C語言二級) 第1題 有以下程序 void fun1 (char*p) { char*q; qp; while(*q!\0) { (*Q); q; } } main() { char a[]{"Program"},*p; p&a[3]; fun1(p); print…