最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java中字符串常見(jiàn)題之String相關(guān)講解

 更新時(shí)間:2019年01月14日 17:03:36   作者:Zy_JiBai  
今天小編就為大家分享一篇關(guān)于Java中字符串常見(jiàn)題之String相關(guān)講解,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧

今天給大家?guī)?lái)的是在面試中經(jīng)常被問(wèn)到的一道題:

無(wú)論在Java還是Android中,String是一個(gè)很常見(jiàn)的類,但是大家真的很了解嗎,我這里有幾個(gè)題:

1.

String str1 = "abc";
String str2 = new String("abc");

這兩種創(chuàng)建String對(duì)象的方法有什么不同?

2.

String s = "a" + "b" + "c" + "d";

這里面一共創(chuàng)建了多少對(duì)象?

這兩道題昨天給筆者搞得是一臉懵逼,后來(lái)一聽(tīng)這是一道很經(jīng)典的面試題,就趕快查閱各種資料,現(xiàn)在已經(jīng)解決了。

在解決這兩個(gè)題之前,我們先來(lái)明確幾個(gè)知識(shí)點(diǎn),相信把這幾個(gè)知識(shí)點(diǎn)弄完之后再回頭看這兩個(gè)題,就很簡(jiǎn)單了:

  • 1.引用在棧內(nèi)存中存儲(chǔ),對(duì)象在堆內(nèi)存中存儲(chǔ)。
  • 2.String對(duì)象不可變。
  • 3.String創(chuàng)建對(duì)象的形式:
  • 4.字符串常量池的意義:
  • 5.intern()方法使用。

我們首先來(lái)開(kāi)第一個(gè):

引用在棧內(nèi)存中存儲(chǔ),對(duì)象在堆內(nèi)存中存儲(chǔ)。

這個(gè)是我粗略畫(huà)的一張圖,這張圖可能不是很準(zhǔn)確,但是我只想表達(dá)一個(gè)意思,我們的棧內(nèi)存,存放的是我們對(duì)象的引用和我們基本數(shù)據(jù)類型的值。而堆內(nèi)存中存放的是我們的對(duì)象。就是這么簡(jiǎn)單。

為什么說(shuō)String對(duì)象不可變

這里我們用一下大佬的圖:

如果用代碼表示上面的圖,那就是:

String s = "abcd";
s = s + "el";

如果沒(méi)有上面這張圖,大家可能會(huì)覺(jué)得我們只是給s對(duì)象后面加了一個(gè)el,這不還是原來(lái)的s嗎?不,我們說(shuō)的String對(duì)象不可變就是這個(gè)意思,當(dāng)我們給s再加上el時(shí)候,新的字符串a(chǎn)bcdel被存放到了一個(gè)新的內(nèi)存中。已經(jīng)不是原來(lái)的內(nèi)存了。所以說(shuō)String對(duì)象不可變,如果變了,那就已經(jīng)變成了一個(gè)新的對(duì)象。

那說(shuō)到這里大家可能會(huì)返回去看我寫(xiě)的第二個(gè)問(wèn)題:按你的說(shuō)法這不就7個(gè)對(duì)象嗎?abcd各占一個(gè),每次+到一起都要重新生成對(duì)象,一共生成了7個(gè)對(duì)象。話是沒(méi)錯(cuò),但是我想說(shuō)這道題說(shuō)多解,等我們講完了下面這兩個(gè)知識(shí)點(diǎn),這道題就完全解開(kāi)了。

String創(chuàng)建對(duì)象的形式:

正如我們上面看到的,String有兩種創(chuàng)建對(duì)象的形式:

1.字面量形式:

String str = "asd";

2.標(biāo)準(zhǔn)的new形式:

String str = new String("asd");

字符串常量池的意義:

字符串常量池,又稱為字符串在字面量池。大家不要他想象的多么高深額,其實(shí)說(shuō)白了他就是一塊內(nèi)存,它里面存放的是我們的字符串的引用。

大家可能疑問(wèn)這個(gè)東西有什么意義:假如我們要?jiǎng)?chuàng)建一個(gè)字符串,"a" + "b" + "c" + ....+ 我們+了一萬(wàn)次,那么按照上面的說(shuō)法,我們是不是為了創(chuàng)建一個(gè)很長(zhǎng)的字符串,創(chuàng)建了很多的對(duì)象。這樣不但有的字符串被重復(fù)的創(chuàng)建了,而且占用了很多不必要的內(nèi)存,代價(jià)有點(diǎn)大。

我們的JVM為了減少字符串的重復(fù)創(chuàng)建,維護(hù)了一個(gè)特殊的內(nèi)存:就是這個(gè)字符串常量池。

在這個(gè)字符串常量池中,存放著我們字符串對(duì)象的引用。下面我們根據(jù)字符串創(chuàng)建對(duì)象的兩種形式來(lái)說(shuō)明一下常量池是如何存放String對(duì)象引用的:

1.通過(guò)字面量創(chuàng)建String對(duì)象:

我們舉個(gè)例子,String str = "abc";我們通過(guò)字面量形式創(chuàng)建一個(gè)值為"abc"的對(duì)象,首先我們判斷常量池中是否存在一個(gè)引用,這個(gè)引用的值也是"abc",如果有這個(gè)值,那么我們就從常量池中拿到這個(gè)引用,返回給str。

如果沒(méi)有,那么我們就創(chuàng)建這個(gè)對(duì)象,然后把str這個(gè)引用值放到常量池中。

在這里我們要明確幾個(gè)點(diǎn)了:

  • 1首先常量池存放的不是字符串對(duì)象,而是字符串對(duì)象的引用。
  • 2.無(wú)論常量池中是否存在這個(gè)對(duì)象的引用,最后結(jié)果都會(huì)存放有這個(gè)引用。
  • 3.該方法可能不會(huì)創(chuàng)建新的對(duì)象。

2.通過(guò)new創(chuàng)建String對(duì)象。

這里其實(shí)只有一句話,無(wú)論常量池中是否存在相同值的引用,至少創(chuàng)建一個(gè)對(duì)象。因?yàn)椴还軇e的,new這個(gè)語(yǔ)法就一定會(huì)創(chuàng)建一個(gè)新的對(duì)象,然后我們要看構(gòu)造方法中的字符串,如果常量池中存在與該字符串相同值的引用,那么就不會(huì)創(chuàng)建新的對(duì)象,反之會(huì)創(chuàng)建對(duì)象之后,在常量池中存放這個(gè)引用。

這樣看起來(lái)我們的常量池的意義就很明確了,減少重復(fù)創(chuàng)建String對(duì)象,從而減少不必要的內(nèi)存消耗。

如果要說(shuō)他的弊端的話,應(yīng)該就是犧牲了CPU的計(jì)算時(shí)間來(lái)?yè)Q取空間吧,因?yàn)椴檎沂欠裼邢嗤瑑?nèi)容的引用是CPU耗時(shí)計(jì)算,但是與前者占用內(nèi)存相比,這個(gè)還是算不了什么的吧(筆者自己觀點(diǎn),沒(méi)有官方支持哈哈)。

intern()方法使用

最后我們來(lái)看一下這個(gè)intern()方法,這個(gè)方法其實(shí)理解為查看常量池中是否存在對(duì)應(yīng)內(nèi)容的引用。如果有他會(huì)返回常量池中的引用,如果沒(méi)有則會(huì)將當(dāng)前String的引用放入常量池。

我們舉幾個(gè)例子對(duì)比下就好:

public static void main(String[] args) { 
 String str1 = "gfzy";
 String str2 = str1.intern();
 System.out.println(str1 == str2);
}

他的結(jié)果是true。很簡(jiǎn)單,我們首先通過(guò)字面量形式創(chuàng)建了一個(gè)“gfzy”對(duì)象,此時(shí)常量池中沒(méi)有相同內(nèi)容引用,所以常量池存放str1的引用。

然后str2為str1的.intern()方法,現(xiàn)在常量池中存在“gfzy”這個(gè)內(nèi)容的引用,所以我們返回這個(gè)引用,也就是str1,所以str1和str2指向同一個(gè)引用。

public static void main(String[] args) { 
 String str1 = new String("gfzy");
 String str2 = "gfzy";
 System.out.println(str1 == str2);
}

這個(gè)結(jié)果為false,首先我們看到str1是new了一個(gè)對(duì)象,所以他肯定是在堆內(nèi)存中一塊新的內(nèi)存,而構(gòu)造方法中的“gfzy”,首先在常量池中會(huì)拿到他的引用,然后返回這個(gè)引用。

str2直接拿到了常量池中的引用,所以一個(gè)是堆內(nèi)存新創(chuàng)建的,一個(gè)是原來(lái)常量池中的引用,兩者指向不是一個(gè)內(nèi)存,所以是false。

而如果是這樣呢:

public static void main(String[] args) { 
 String str1 = new String("gfzy").intern();
 String str2 = "gfzy";
 System.out.println(str1 == str2);
}

這個(gè)結(jié)果為true。在原來(lái)的基礎(chǔ)上只是添加了一個(gè)inter方法,在new String("gfzy");時(shí)候,現(xiàn)在常量池中已經(jīng)有了這個(gè)引用。而現(xiàn)在intern,我們會(huì)拿到常量池中的引用,所以str1為常量池中的引用,str2和上面一樣,所以返回true。

現(xiàn)在這幾個(gè)問(wèn)題都解決完了,我們?cè)俜祷仡^看之前的兩個(gè)問(wèn)題,第一個(gè)問(wèn)題就很簡(jiǎn)單了,而我們剛才也說(shuō)過(guò)了。

第二個(gè)是看常量池中是否已經(jīng)存在了對(duì)應(yīng)的引用,如果沒(méi)有,那么是"a","b","ab","c","abc","d","abcd"七個(gè)對(duì)象,如果常量池中存在引用,那么只創(chuàng)建了一個(gè)“abcd”(這個(gè)是編譯器優(yōu)化后的結(jié)果,其實(shí)筆者這里也是有點(diǎn)懵逼,個(gè)人感覺(jué)應(yīng)該是3個(gè)額,希望這個(gè)問(wèn)題有讀者多多留言,幫我解答一下這個(gè)問(wèn)題)。

總結(jié)

以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請(qǐng)查看下面相關(guān)鏈接

相關(guān)文章

  • java使用jacob實(shí)現(xiàn)word轉(zhuǎn)pdf

    java使用jacob實(shí)現(xiàn)word轉(zhuǎn)pdf

    這篇文章主要為大家詳細(xì)介紹了java使用jacob實(shí)現(xiàn)word轉(zhuǎn)pdf,通過(guò)調(diào)用模板文件,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-12-12
  • 詳解SpringBoot定時(shí)任務(wù)功能

    詳解SpringBoot定時(shí)任務(wù)功能

    這篇文章主要介紹了SpringBoot定時(shí)任務(wù)功能詳細(xì)解析,這次的功能開(kāi)發(fā)過(guò)程中也算是對(duì)其內(nèi)涵的進(jìn)一步了解,以后遇到定時(shí)任務(wù)的處理也更清晰,更有效率了,對(duì)SpringBoot定時(shí)任務(wù)相關(guān)知識(shí)感興趣的朋友一起看看吧
    2022-05-05
  • java(jdk)環(huán)境變量配置(XP、win7、win8)圖文教程詳解

    java(jdk)環(huán)境變量配置(XP、win7、win8)圖文教程詳解

    對(duì)于初學(xué)java的同學(xué)來(lái)說(shuō),第一件事不是寫(xiě)hello world,而是搭建好java開(kāi)發(fā)環(huán)境,下載jdk,安裝,配置環(huán)境變量。這些操作在xp、win7、win8不同的操作系統(tǒng)里面配置不太一樣,下面通過(guò)本文給大家介紹如何在上面不同操作系統(tǒng)下配置
    2017-03-03
  • java根據(jù)模板實(shí)現(xiàn)填充word內(nèi)容并轉(zhuǎn)換為pdf

    java根據(jù)模板實(shí)現(xiàn)填充word內(nèi)容并轉(zhuǎn)換為pdf

    這篇文章主要為大家詳細(xì)介紹了java如何根據(jù)模板實(shí)現(xiàn)填充word內(nèi)容并轉(zhuǎn)換為pdf,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2025-04-04
  • Java解析微信獲取手機(jī)號(hào)信息的示例步驟

    Java解析微信獲取手機(jī)號(hào)信息的示例步驟

    在微信中,用戶手機(jī)號(hào)的獲取通常是通過(guò)微信小程序的getPhoneNumber接口來(lái)實(shí)現(xiàn)的,下面通過(guò)一個(gè)基于Java的示例,展示了如何接收并解密從微信小程序傳遞過(guò)來(lái)的加密手機(jī)號(hào)信息,感興趣的朋友一起看看吧
    2024-06-06
  • java中循環(huán)遍歷刪除List和Set集合中元素的方法(推薦)

    java中循環(huán)遍歷刪除List和Set集合中元素的方法(推薦)

    下面小編就為大家?guī)?lái)一篇java中循環(huán)遍歷刪除List和Set集合中元素的方法(推薦)。小編覺(jué)得挺不錯(cuò)的,在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-12-12
  • http中g(shù)et請(qǐng)求與post請(qǐng)求區(qū)別及如何選擇

    http中g(shù)et請(qǐng)求與post請(qǐng)求區(qū)別及如何選擇

    這篇文章主要介紹了http中g(shù)et請(qǐng)求與post請(qǐng)求在應(yīng)用中應(yīng)該如何選擇,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2021-09-09
  • springboot實(shí)現(xiàn)執(zhí)行sql語(yǔ)句打印到控制臺(tái)

    springboot實(shí)現(xiàn)執(zhí)行sql語(yǔ)句打印到控制臺(tái)

    這篇文章主要介紹了springboot實(shí)現(xiàn)執(zhí)行sql語(yǔ)句打印到控制臺(tái)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • 淺析java程序中hibernate的應(yīng)用總結(jié)

    淺析java程序中hibernate的應(yīng)用總結(jié)

    hibernate可以理解為是一個(gè)中間件它負(fù)責(zé)把java程序的sql語(yǔ)句接收過(guò)來(lái)發(fā)送到數(shù)據(jù)庫(kù),而數(shù)據(jù)庫(kù)返回來(lái)的信息hibernate接收之后直接生成一個(gè)對(duì)象傳給java
    2013-07-07
  • Java 讀取網(wǎng)絡(luò)圖片存儲(chǔ)到本地并生成縮略圖

    Java 讀取網(wǎng)絡(luò)圖片存儲(chǔ)到本地并生成縮略圖

    用Java做開(kāi)發(fā)經(jīng)常需要處理圖片。本文就來(lái)看一下如何保存圖片到本地并生成縮略圖
    2021-05-05

最新評(píng)論

益阳市| 玛多县| 霞浦县| 仪陇县| 蒲城县| 黄浦区| 额济纳旗| 孙吴县| 宜宾县| 宜丰县| 木兰县| 宿松县| 延寿县| 遂川县| 慈溪市| 阳城县| 类乌齐县| 泊头市| 尼玛县| 曲阜市| 阿鲁科尔沁旗| 抚远县| 华池县| 丹棱县| 洮南市| 北流市| 全南县| 深州市| 广昌县| 台东市| 昭苏县| 库车县| 于都县| 汕尾市| 调兵山市| 福鼎市| 辽宁省| 淮阳县| 景洪市| 锡林郭勒盟| 通州市|