下面小編就為大家帶來一篇老生常談Java String字串(必看篇)。小編覺得蠻不錯的,現在就分享給大家,也給大家做個參考。一起跟著小編過來看看吧
Java中字串物件建立有兩種形式,一種是字面量形式,如String str = "hello";,另一種就是使用new這種標準的建構物件的方法,如String str = new String("hello");
對於這樣的常識,不再贅述。
首先String類別是final類,為什麼定義成final形式呢?
簡單說,對於如此高頻率被使用的資料類型,設計者們認為已經設計的足夠優秀了,不需要被繼承,否則胡亂繼承重寫可能會降低程式的性能。
如標題所述,既然深入,那我們就挖下String在jvm層面的小動作。
先解釋字面量創建的形式:
#當程式碼中出現字面量形式建立字串物件時,JVM首先會對這個字面量進行檢查,如果字串常數池中存在相同內容的字串物件的引用,則將這個引用返回,否則新的字串物件被創建,然後將這個引用放入字串常數池,並返回該引用。
如下:
String str1 = "hello" ;
當我們第一次創建的時候,這裡我們認為沒有內容為hello的物件存在。 JVM透過字串常數池查找不到內容為hello的字串物件存在,那麼會建立這個字串對象,然後將剛建立的物件的引用放入到字串常數池中,並且將引用傳回給變數str1
如果接下來有這樣一段程式碼
String str2 = "hello" ;
同樣JVM還是要偵測這個字面量,JVM透過找出字串常數池,發現內容為」hello」字串物件存在,於是將已經存在的字串物件的參考傳回給變數str2。注意這裡不會重新建立新的字串物件。
驗證是否為str1和str2是否指向同一對象,我們可以透過這段程式碼
System.out.println(str1 == str2);
結果為true。
第二個使用new建立:
String str3 = new String("hello");
當我們使用了new來建構字串物件的時候,不管字串常數池中有沒有相同內容的物件的引用,新的字串物件都會創建。因此我們使用下面程式碼測試一下,
String str3 = new String("hello"); System.out.println(str1 == str3);
結果為false。說明這兩個引用指向不同的物件。
intern
對於上面使用new建立的字串對象,如果想將這個物件的參考加入到字串常數池,可以使用intern方法。
呼叫intern後,首先檢查字串常數池中是否有該物件的引用,如果存在,則將這個引用傳回給變量,否則將引用加入並傳回給變數。
String str4 = str3.intern(); System.out.println(str4 == str1);
結果為true。
疑難問題
前提條件?
字串常數池實作的前提條件就是Java中String物件是不可變的,這樣可以安全地保證多個變數共享同一個物件。如果Java中的String物件可變的話,一個引用運算改變了物件的值,那麼其他的變數也會受到影響,顯然這樣是不合理的。
引用 or 物件
字串常數池中存放的時引用還是對象,這個問題是最常見的。字串常數池存放的是物件引用,不是物件。在Java中,物件都創建在堆疊記憶體中。字串常數池存在於堆記憶體中的永久代
優缺點
字串常數池的好處就是減少相同內容字串的創建,節省記憶體空間。
如果硬要說弊端的話,就是犧牲了CPU運算時間來換空間。 CPU計算時間主要用於在字串常數池中尋找是否有對內容相同物件的參考。不過其內部實作為HashTable,所以計算成本較低。
GC回收?
因為字串常數池中持有了共享的字串物件的引用,這就是說是不是會導致這些物件無法回收?
首先問題中共享的物件一般情況下都比較小。據我查證了解,在早期的版本中確實存在這樣的問題,但是隨著弱引用的引入,目前這個問題應該沒有了。
intern使用?
#关于使用intern的前提就是你清楚自己确实需要使用。比如,我们这里有一份上百万的记录,其中记录的某个值多次为美国加利福尼亚州,我们不想创建上百万条这样的字符串对象,我们可以使用intern只在内存中保留一份即可。
总有例外?
你知道下面的代码,会创建几个字符串对象,在字符串常量池中保存几个引用么?
String test = "a" + "b" + "c";
答案是只创建了一个对象,在常量池中也只保存一个引用。我们使用javap反编译看一下即可得知。
实际上在编译期间,已经将这三个字面量合成了一个。这样做实际上是一种优化,避免了创建多余的字符串对象,也没有发生字符串拼接问题。
以上是Java中關於String字串的詳細介紹的詳細內容。更多資訊請關注PHP中文網其他相關文章!

新興技術對Java的平台獨立性既有威脅也有增強。 1)雲計算和容器化技術如Docker增強了Java的平台獨立性,但需要優化以適應不同雲環境。 2)WebAssembly通過GraalVM編譯Java代碼,擴展了其平台獨立性,但需與其他語言競爭性能。

不同JVM實現都能提供平台獨立性,但表現略有不同。 1.OracleHotSpot和OpenJDKJVM在平台獨立性上表現相似,但OpenJDK可能需額外配置。 2.IBMJ9JVM在特定操作系統上表現優化。 3.GraalVM支持多語言,需額外配置。 4.AzulZingJVM需特定平台調整。

平台獨立性通過在多種操作系統上運行同一套代碼,降低開發成本和縮短開發時間。具體表現為:1.減少開發時間,只需維護一套代碼;2.降低維護成本,統一測試流程;3.快速迭代和團隊協作,簡化部署過程。

Java'splatformindependencefacilitatescodereusebyallowingbytecodetorunonanyplatformwithaJVM.1)Developerscanwritecodeonceforconsistentbehavioracrossplatforms.2)Maintenanceisreducedascodedoesn'tneedrewriting.3)Librariesandframeworkscanbesharedacrossproj

要解決Java應用程序中的平台特定問題,可以採取以下步驟:1.使用Java的System類查看系統屬性以了解運行環境。 2.利用File類或java.nio.file包處理文件路徑。 3.根據操作系統條件加載本地庫。 4.使用VisualVM或JProfiler優化跨平台性能。 5.通過Docker容器化確保測試環境與生產環境一致。 6.利用GitHubActions在多個平台上進行自動化測試。這些方法有助於有效地解決Java應用程序中的平台特定問題。

類加載器通過統一的類文件格式、動態加載、雙親委派模型和平台無關的字節碼,確保Java程序在不同平台上的一致性和兼容性,實現平台獨立性。

Java編譯器生成的代碼是平台無關的,但最終執行的代碼是平台特定的。 1.Java源代碼編譯成平台無關的字節碼。 2.JVM將字節碼轉換為特定平台的機器碼,確保跨平台運行但性能可能不同。

多線程在現代編程中重要,因為它能提高程序的響應性和資源利用率,並處理複雜的並發任務。 JVM通過線程映射、調度機制和同步鎖機制,在不同操作系統上確保多線程的一致性和高效性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

Video Face Swap
使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

SublimeText3 英文版
推薦:為Win版本,支援程式碼提示!

SublimeText3 Linux新版
SublimeText3 Linux最新版

WebStorm Mac版
好用的JavaScript開發工具

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),