Java String類相關知識梳理(含字符串常量池(String Pool)知識)

目錄java

1. String類是什麼數組

  1.1 定義安全

  1.2 類結構數據結構

  1.3 所在的包app

2. String類的底層數據結構測試

3. 關於 intern() 方法(重點)ui

  3.1 做用spa

  3.2 字符串常量池(String Pool)線程

4. String類所用的鏈接符code

5. String類的主要做用(簡)

 

正文

1. String類是什麼

  1.1 定義

  String類表示字符串。Java程序中的全部字符串都是這個String的實例,好比"abc"。字符串爲常數,它們的值在建立以後不能更改。由於字符串對象是不可變的,避免了現線程安全問題的出現,因此能夠共享它們。

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

  問:「字符串爲常數,它們的值在建立以後不能更改」——①這句話的具體表現(從String的使用角度出發)?②爲何要一經建立就不可更改?③怎麼作到一經建立就不可更改的?

    答:

    ①經過調用String的方法咱們能夠發現,String並未真正提供「字符串的修改」方法,諸如replace這類的字符串替換方法,也只是建立一個新的字符串來替換,而非在原字符串上進行替換;

    ②這個問題從字符串的使用場景來解釋比較好理解:從用戶使用時的安全性考慮(線程安全),八種基本數據類型的「複製」是再新建立一份相同的數據,而String其實也至關因而一種基本的數據類型,只是它有引用,比較複雜一些,因此字符串要一經建立就不能更改。

    ③封裝:雖然String的底層數據結構是char數組(數組的內容是能夠更改的),可是,String將該字段聲明爲private,且並不對外暴露修改數組內容的方法。

  1.2 類結構

public final class String implements java.io.Serializable, Comparable<String>, CharSequence{……}

  ① final:String類不能被繼承;

  ② Serializable:可序列化;

  ③ Comparable<String>:用於字符串之間的比較;

  1.3 所在的包:java.lang

  java.lang包是java語言的核心,它提供了java中的基礎類。包括基本Object類、Class類、String類、基本類型的包裝類、基本的數學類等等最基本的類。

 

2. String類的底層數據結構

private final char value[];//不可變的字符數組

  問1. 若是說String的底層數據結構是「不可變的char數組」,那不該該是聲明爲「 private final char[] value;」嗎?

    答:這也是數組的一種聲明方式,只是比較少見、少用,或許由於歷史緣由因此String保留使用着這種不經常使用的數組聲明方式。

  問2. 不可變的字符數組的聲明只能保證String對象的引用不可變,而用了char數組來做爲存儲結構,只能保證字符串一經聲明其長度不可變,可是數組中存儲的內容時能夠改變的,從何保證字符串一經聲明就不能再變呢?

    答:見 1.1的第③點;

  

3. 關於 intern() 方法(重點)

  3.1 做用:該方法用於返回字符串對象的規範表示形式。

public native String intern();// native方法,看不到具體實現。

  當調用intern方法時:

    ①若是字符串常量池中已經包含了一個由equals(object)方法肯定的String對象的字符串,則返回池中的字符串。

    ②不然,將這個 String對象添加到池中(這是JDK1.8中intern()方法的註釋給出的說明,但經過下面的測試,我認爲是「將這個String對象的字符串添加到池中」會更好理解),並返回對這個String對象的引用。

    @Test
    public void test() {

        // 池中沒有相應的字符串內容:
        String s1 = new String("hello");// 在堆中生成"hello"字符串對象
        String s2 = s1.intern();// 執行「s1.intern()」時,String Pool中沒有"hello",會直接先將s1對象複製到池中
        System.out.println(s1 == s2); // false
        System.out.println(s1.intern()); // hello

        // 池中有:
        String s3 = "world"; // 直接在String Pool中生成"world"字符串
        String s4 = s3.intern(); // 從池中拿"world"字符串返回給s4
        System.out.println(s3 == s4); // true
    }

  3.2 字符串常量池(String Pool)

  字符串常量池最初是空的,由類 String私下維護。

  (1)在哪兒

    在JDK6及以前版本:字符串常量池是放在永久代中;

    在JDK7版本中:字符串常量池被移到了堆中。

  (2)數據結構

    在HotSpot VM中字符串常量池是經過一個StringTable類(一個Hash表,並不是java實現類,因此知道便可)實現的;這個StringTable在每一個HotSpot VM的實例中只有一份,被全部的類共享;

  (3)存放的內容

    在JDK6及以前版本:String Pool裏放的都是字符串常量;

    在JDK7.0中:因爲String.intern()發生了改變,所以String Pool中也能夠存放放於堆內的字符串對象的引用。

  (4)特性:常量池中不存在兩個相同的對象

  (5)字符串常量池存在的意義(爲何要有它?):避免字符串常量的重複建立,節省內存空間。

  (6)什麼狀況下生成的字符串纔會被放到String Pool中?

    ① 字面量:代碼中直接使用雙引號引着的字符串都會被存儲到字符串常量池中,如:String abc = "abc";;

    ② 調用String的 intern()方法,若是字符串內容是字符串常量池中沒有的,那麼會先複製一分內容到字符串常量池中;

 

4. String類所用的鏈接符

  Java語言爲「+」鏈接符以及將對象轉換爲字符串提供了特殊的支持:

  字符串對象可使用「+」鏈接其餘對象。其實字符串鏈接是經過StringBuilder(或 StringBuffer)及其 append()方法 實現的。

  字符串轉換是經過 toString()方法實現的,該方法由Object定義,並由Java中的全部類繼承。

 

5. String類的主要做用(簡) 

  ①檢查序列的單個字符、  ②比較字符串、  ③搜索字符串、  ④提取子字符串  ⑤建立一個字符串的副本的方法,  ⑥大小寫轉換;  ⑦更多;

相關文章
相關標籤/搜索