欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java中字符串常見題之String相關講解

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

今天給大家?guī)淼氖窃诿嬖囍薪洺1粏柕降囊坏李}:

無論在Java還是Android中,String是一個很常見的類,但是大家真的很了解嗎,我這里有幾個題:

1.

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

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

2.

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

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

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

在解決這兩個題之前,我們先來明確幾個知識點,相信把這幾個知識點弄完之后再回頭看這兩個題,就很簡單了:

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

我們首先來開第一個:

引用在棧內存中存儲,對象在堆內存中存儲。

這個是我粗略畫的一張圖,這張圖可能不是很準確,但是我只想表達一個意思,我們的棧內存,存放的是我們對象的引用和我們基本數(shù)據(jù)類型的值。而堆內存中存放的是我們的對象。就是這么簡單。

為什么說String對象不可變

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

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

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

如果沒有上面這張圖,大家可能會覺得我們只是給s對象后面加了一個el,這不還是原來的s嗎?不,我們說的String對象不可變就是這個意思,當我們給s再加上el時候,新的字符串abcdel被存放到了一個新的內存中。已經不是原來的內存了。所以說String對象不可變,如果變了,那就已經變成了一個新的對象。

那說到這里大家可能會返回去看我寫的第二個問題:按你的說法這不就7個對象嗎?abcd各占一個,每次+到一起都要重新生成對象,一共生成了7個對象。話是沒錯,但是我想說這道題說多解,等我們講完了下面這兩個知識點,這道題就完全解開了。

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

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

1.字面量形式:

String str = "asd";

2.標準的new形式:

String str = new String("asd");

字符串常量池的意義:

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

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

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

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

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

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

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

在這里我們要明確幾個點了:

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

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

這里其實只有一句話,無論常量池中是否存在相同值的引用,至少創(chuàng)建一個對象。因為不管別的,new這個語法就一定會創(chuàng)建一個新的對象,然后我們要看構造方法中的字符串,如果常量池中存在與該字符串相同值的引用,那么就不會創(chuàng)建新的對象,反之會創(chuàng)建對象之后,在常量池中存放這個引用。

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

如果要說他的弊端的話,應該就是犧牲了CPU的計算時間來換取空間吧,因為查找是否有相同內容的引用是CPU耗時計算,但是與前者占用內存相比,這個還是算不了什么的吧(筆者自己觀點,沒有官方支持哈哈)。

intern()方法使用

最后我們來看一下這個intern()方法,這個方法其實理解為查看常量池中是否存在對應內容的引用。如果有他會返回常量池中的引用,如果沒有則會將當前String的引用放入常量池。

我們舉幾個例子對比下就好:

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

他的結果是true。很簡單,我們首先通過字面量形式創(chuàng)建了一個“gfzy”對象,此時常量池中沒有相同內容引用,所以常量池存放str1的引用。

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

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

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

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

而如果是這樣呢:

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

這個結果為true。在原來的基礎上只是添加了一個inter方法,在new String("gfzy");時候,現(xiàn)在常量池中已經有了這個引用。而現(xiàn)在intern,我們會拿到常量池中的引用,所以str1為常量池中的引用,str2和上面一樣,所以返回true。

現(xiàn)在這幾個問題都解決完了,我們再返回頭看之前的兩個問題,第一個問題就很簡單了,而我們剛才也說過了。

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

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,謝謝大家對腳本之家的支持。如果你想了解更多相關內容請查看下面相關鏈接

相關文章

  • SpringCloud Open feign 使用okhttp 優(yōu)化詳解

    SpringCloud Open feign 使用okhttp 優(yōu)化詳解

    這篇文章主要介紹了SpringCloud Open feign 使用okhttp 優(yōu)化詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • springboot無法從靜態(tài)上下文中引用非靜態(tài)變量的解決方法

    springboot無法從靜態(tài)上下文中引用非靜態(tài)變量的解決方法

    這篇文章主要介紹了springboot無法從靜態(tài)上下文中引用非靜態(tài)變量的解決方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-06-06
  • mybatis攔截器無法注入spring bean的問題解決

    mybatis攔截器無法注入spring bean的問題解決

    本文主要介紹了mybatis攔截器無法注入spring bean的問題解決,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2022-02-02
  • JavaCV與FFmpeg音視頻流處理技巧總結大全

    JavaCV與FFmpeg音視頻流處理技巧總結大全

    JavaCV是一個開源的Java接口,它為幾個著名的計算機視覺庫(如OpenCV、FFmpeg)提供了Java封裝,這篇文章主要給大家介紹了關于JavaCV與FFmpeg音視頻流處理技巧總結的相關資料,需要的朋友可以參考下
    2024-05-05
  • Java?Date(日期)對象進行格式化的思路詳解

    Java?Date(日期)對象進行格式化的思路詳解

    Date類是經常會使用到的一個用來處理日期、時間的一個類。Date類是在java.util包下的Date類,這篇文章主要介紹了Java?Date(日期)對象如何進行格式化呢,需要的朋友可以參考下
    2022-09-09
  • Spring MVC整合 freemarker及使用方法

    Spring MVC整合 freemarker及使用方法

    Spring MVC是一種基于Java的實現(xiàn)了Web MVC設計模式的請求驅動類型的輕量級Web框架,這篇文章主要介紹了Spring MVC整合 freemarker及使用方法,需要的朋友可以參考下
    2019-07-07
  • 在Java中判斷兩個Long對象是否相等

    在Java中判斷兩個Long對象是否相等

    這篇文章主要介紹了在Java中判斷兩個Long對象是否相等的操作,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • java實現(xiàn)簡易版圖形界面計算器

    java實現(xiàn)簡易版圖形界面計算器

    這篇文章主要為大家詳細介紹了java實現(xiàn)簡易版圖形界面計算器,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • Swing常用組件之單選按鈕和復選框

    Swing常用組件之單選按鈕和復選框

    Swing是一個用于開發(fā)Java應用程序用戶界面的開發(fā)工具包,這篇文章主要介紹了Swing常用組件之單選按鈕和復選框,感興趣的朋友可以參考一下
    2016-05-05
  • spring cloud學習教程之config修改配置詳解

    spring cloud學習教程之config修改配置詳解

    這篇文章主要給大家介紹了關于spring cloud學習教程之config修改配置的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。
    2017-09-09

最新評論