最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

深入理解Java的String類

2021-05-06 09:26 作者:光耀三十洲  | 我要投稿

String類

在Java中String類的使用的頻率可謂相當高。它是Java語言中的核心類,在java.lang包下,主要用于字符串的比較、查找、拼接等等操作。如果要深入理解一個類,最好的方法就是看看源碼:

學習更多,請點擊:https://www.bilibili.com/video/BV1tZ4y1F7eK

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV135411w7Jg

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7fm

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7mF

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1GZ4y1F7qW

從源碼中,可以看出以下幾點:

  • String類被final關(guān)鍵字修飾,表示String類不能被繼承,并且它的成員方法都默認為final方法。

  • String類實現(xiàn)了Serializable、CharSequence、 Comparable接口。

  • String類的值是通過char數(shù)組存儲的,并且char數(shù)組被private和final修飾,字符串一旦創(chuàng)建就不能再修改。

下面通過幾個問題不斷加深對String類的理解。

學習更多,請點擊:https://www.bilibili.com/video/BV1tZ4y1F7eK

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV135411w7Jg

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7fm

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7mF

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1GZ4y1F7qW

問題一

上面說字符串一旦創(chuàng)建就不能再修改,String類提供的replace()方法不就可以替換修改字符串的內(nèi)容嗎?

實際上replace()方法并沒有對原字符串進行修改,而是創(chuàng)建了一個新的字符串返回,看看源碼就知道了。

其他方法也是一樣,無論是sub、concat還是replace操作都不是在原有的字符串上進行的,而是重新生成了一個新的字符串對象。

學習更多,請點擊:https://www.bilibili.com/video/BV1tZ4y1F7eK

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV135411w7Jg

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7fm

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7mF

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1GZ4y1F7qW

問題二

為什么要使用final關(guān)鍵字修飾String類?

首先要講final修飾類的作用,被final修飾的類不能被繼承,類中的所有成員方法都會被隱式地指定為final方法。也就是不能擁有子類,成員方法也不能被重寫。

回到問題,String類被final修飾主要基于安全性和效率兩點考慮。

  • 安全性

因為字符串是不可變的,所以是多線程安全的,同一個字符串實例可以被多個線程共享。這樣便不用因為線程安全問題而使用同步。字符串自己便是線程安全的。

String被許多的Java類(庫)用來當做參數(shù),比如網(wǎng)絡連接地址URL,文件路徑path,還有反射機制所需要的String參數(shù)等,假若String不是固定不變的,將會引起各種安全隱患。

  • 效率

字符串不變性保證了hash碼的唯一性,因此可以放心的進行緩存,這也是一種性能優(yōu)化手段,意味著不必每次都取計算新的哈希碼。

只有當字符串是不可變的,字符串池才有可能實現(xiàn),字符串常量池是java堆內(nèi)存中一個特殊的存儲區(qū)域,當創(chuàng)建一個String對象,假如此字符串值已經(jīng)存在于常量池中,則不會創(chuàng)建一個新的對象,而是引用已經(jīng)存在的對象。

字符串常量池

字符串的分配和其他對象分配一樣,是需要消耗高昂的時間和空間的,而且字符串我們使用的非常多。JVM為了提高性能和減少內(nèi)存的開銷,所以在實例化字符串的時候使用字符串常量池進行優(yōu)化。

學習更多,請點擊:https://www.bilibili.com/video/BV1tZ4y1F7eK

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV135411w7Jg

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7fm

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7mF

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1GZ4y1F7qW

池化思想其實在Java中并不少見,字符串常量池也是類似的思想,當創(chuàng)建字符串時,JVM會首先檢查字符串常量池,如果該字符串已經(jīng)存在常量池中,那么就直接返回常量池中的實例引用。如果字符串不存在常量池中,就會實例化該字符串并且將其放到常量池中。

我們可以寫個簡單的例子證明:

還有一個面試中經(jīng)常問的,new String(“abc”)創(chuàng)建了幾個對象?

這可能就是想考你對字符串常量池的理解,我一般回答是一個或者兩個對象。

如果之前"abc"字符串沒有使用過,毫無疑問是創(chuàng)建兩個對象,堆中創(chuàng)建了一個String對象,字符串常量池創(chuàng)建了一個,一共兩個。

如果之前已經(jīng)使用過了"abc"字符串,則不會再在字符串常量池創(chuàng)建對象,而是從字符串常量緩沖區(qū)中獲取,只會在堆中創(chuàng)建一個String對象。

字符串拼接

字符串的拼接在Java中是很常見的操作,但是拼接字符串并不是簡簡單單地使用"+"號即可,還有一些要注意的點,否則會造成效率低下。

學習更多,請點擊:https://www.bilibili.com/video/BV1tZ4y1F7eK

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV135411w7Jg

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7fm

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7mF

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1GZ4y1F7qW

比如下面這段代碼:

在循環(huán)內(nèi)使用+=拼接字符串會有什么問題呢?我們反編譯一下看看就知道了。

其實反編譯后,我們可以看到String類使用"+="拼接的底層其實是使用StringBuilder,先初始化一個StringBuilder對象,然后使用append()方法拼接,最后使用toString()方法得到結(jié)果。

問題在于如果在循環(huán)體內(nèi)使用+=拼接,會創(chuàng)建很多臨時的StringBuilder對象,拼接后再調(diào)用toString()賦給原String對象。這會生成大量臨時對象,嚴重影響性能。

學習更多,請點擊:https://www.bilibili.com/video/BV1tZ4y1F7eK

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV135411w7Jg

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7fm

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7mF

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1GZ4y1F7qW

所以在循環(huán)體內(nèi)進行字符串拼接時,建議使用StringBuilder或者StringBuffer類,例子如下:

StringBuilder和StringBuffer的區(qū)別在于,StringBuffer的方法都被sync關(guān)鍵字修飾,所以是線程安全的,而StringBuilder則是線程不安全的(效率高)。

總結(jié)

回顧一下,本文介紹了String類的不可變的特點,還有字符串常量池的作用,最后簡單地從JVM編譯的層面對字符串拼接提出一點建議。所謂溫故而知新,即使是一些很基礎很常見的類,如果深入去探索的話,也會有一番收獲。

這篇文章就講到這里了,感謝大家的閱讀,希望看完大家能有所收獲!

學習更多,請點擊:https://www.bilibili.com/video/BV1tZ4y1F7eK

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV135411w7Jg

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7fm

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1sf4y1p7mF

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?https://www.bilibili.com/video/BV1GZ4y1F7qW


作者:java技術(shù)愛好者
鏈接:https://juejin.cn/post/6958710820280729631
來源:掘金
著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請注明出處。


深入理解Java的String類的評論 (共 條)

分享到微博請遵守國家法律
科技| 布拖县| 长葛市| 库尔勒市| 延长县| 新巴尔虎左旗| 锡林郭勒盟| 罗城| 静安区| 锦州市| 朝阳区| 莫力| 临漳县| 屏山县| 南昌市| 大城县| 巍山| 吐鲁番市| 洞口县| 千阳县| 晋江市| 灵宝市| 溧水县| 手机| 雷州市| 东宁县| 华安县| 石城县| 北票市| 揭西县| 乐东| 始兴县| 垦利县| 临邑县| 修文县| 沂水县| 安义县| 广安市| 乐陵市| 周至县| 克东县|