目錄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類的主要做用(簡)
①檢查序列的單個字符、 ②比較字符串、 ③搜索字符串、 ④提取子字符串 ⑤建立一個字符串的副本的方法, ⑥大小寫轉換; ⑦更多;