String常量池如何理解?面試一般會問嗎?

IT資訊i


String常量池問題,答主根據自己的理解來簡單說說吧!

為什麼需要有String 的常量池

  • 原因其實就是因為String類是final修飾的,被final修飾的類各位小夥伴應該都知道是不能被基礎的,也就是說創建String類型的變量賦值,在從新給它賦值實際上在內存中是會再次開闢空間來存儲這個值。那麼String類型和其它的引用類型一樣創建會消耗很大內存空間,從而會影響到程序的性能。
  • 所以jvm為了節約資源,給String開闢了一個字符串常量池,那麼每次要創建新的Strig你對象的時候都會到字符串常量池中先去看看有沒有這個值,有的話那就直接引用,不需要創建。沒有的話創建完畢之後在放入到字符串常量池中。

什麼是String常量池

  • 要理解什麼是String常量池需要了解所謂的堆,棧,方法區。這裡我就不做過多解釋,如果有不懂的小夥伴自己區查找資料去看看。這裡我就簡單說說:

  • 堆:一般放對象,那麼也是GC常常光顧的地方

  • 棧:一般放引用

  • 方法區:一般放公共的資源,比如說被Static修飾的靜態成員,包括final修飾的成員;

  • 那麼知道了他們的作用,我們在來通過下面的代碼和內存分配圖來理解理解字符串的常量池:

示例:String a="abc";

String b="abc";

String c=new String("abc");

根據上面的代碼答主自己畫的內存圖:

  • 通過上面的這個圖我們來看看什麼是常量池:

當我們創建了字符串變量a值為“abc”,當我們再次創建字符串變量b值和a一樣,那麼這個時候字符串b會到常量池中區找有沒有“abc”這個值,有就直接引用;當我們在通過new方式再次創建一個對象c,它其實是在堆內存中創建了一個字符串對象,然後最後的值還是指向了字符串常量池中的已經存在的“abc”;

String常量池的作用是什麼

通過上面的說明相信大家應該知道了String常量池的作用了,就是為了增加程序性能,減少頻繁創建String對象帶來的不必要的內存消耗和線程資源。

String面試題會被問到嗎?

一般情況現在的是很少問答關於String的面試題了。如果真的問到了的話其實多半面試官想了解了解你對Java的jvm理解了。可能在幾年前這種類似的問題還會問的稍微多那麼一點點。所以題主還是多花點時間去了解jvm可能會更加好一點。

Java虛擬機內存結構圖

總結:String常量池的存在就是為了增加程序效率的,那麼它的內存圖也不難理解,並且現在的面試中一般也很少去問到這類問題,所以可以花點時間去多學習Java的jvm會比較好點。

以上是答主自己的理解,如果覺得幫到各位了,麻煩給個贊,或者有更好理解的小夥伴可以在下方評論區留言,點個關注我們一起探討探討。


自學JAVA


為了便於理解,舉個例子,有如下代碼段:

String t0 = "helloworld";

String t1 = new String("helloworld");

上面代碼在運行時會在Java虛擬機棧中創建一個String類型變量t0,然後會優先在方法區的運行時常量池中查找是否已經存在相同的字符串,倘若已經存在,棧中t0變量直接指向該字符串;倘若不存在,則在常量池中創建一個"helloworld"字符串,再將棧中t0變量指向該字符串。通過new關鍵字創建字符串對象,首先當前類被加載後,會在方法區的運行時常量池中查找是否已經存在"helloworld"字符串,如果不存在,則將編譯期生成的"helloworld"存到運行時常量池中,如果已存在不存放,在堆中生成一個String類型的對象,棧中t1變量指向該對象。需要注意的是從JDK1.7開始,HotSpot虛擬機將字符串常量移至Java Heap。

這裡再說一下String的intern方法,JDK1.7之前的版本中,intern方法會優先在方法區的運行時常量池中查找是否已經存在相同的字符串,倘若已經存在,則返回已存在的字符串,否則則在常量池中添加一個字符串常量,並返回字符串。因為從JDK1.7開始,HotSpot虛擬機將字符串常量移至Java Heap,intern方法的實現也發生了變化,首先還是會先去查詢常量池中是否已經存在,如果存在,則返回常量池中的字符串,否則不再將字符串拷貝到常量池,而只是在常量池中保存字符串對象的引用。


分享到:


相關文章: