回覆列表
  • 1 # 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方法的實現也發生了變化,首先還是會先去查詢常量池中是否已經存在,如果存在,則返回常量池中的字串,否則不再將字串複製到常量池,而只是在常量池中儲存字串物件的引用。

  • 2 # 自學JAVA

    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會比較好點。

  • 中秋節和大豐收的關聯?
  • 權健若倒下去,它旗下的經銷商利益該由誰來保障?