public class StrTest {
public static void main(String[] args) {
/**
* 情景一:字符串池
* JAVA虛擬機(JVM)中存在着一個字符串池,其中保存着不少String對象;
* 而且能夠被共享使用,所以它提升了效率。
* 因爲String類是final的,它的值一經建立就不可改變。
* 字符串池由String類維護,咱們能夠調用intern()方法來訪問字符串池。
*/
String s1 = "abc";
//↑ 在字符串池建立了一個對象
String s2 = "abc";
//↑ 字符串pool已經存在對象「abc」(共享),因此建立0個對象,累計建立一個對象
System.out.println("s1 == s2 : "+(s1==s2));
//↑ true 指向同一個對象,
System.out.println("s1.equals(s2) : " + (s1.equals(s2)));
//↑ true 值相等
//↑------------------------------------------------------over
/**
* 情景二:關於new String("")
*
*/
String s3 = new String("abc");
//↑ 建立了兩個對象,一個存放在字符串池中,一個存在與堆區中;
//↑ 還有一個對象引用s3存放在棧中
String s4 = new String("abc");
//↑ 字符串池中已經存在「abc」對象,因此只在堆中建立了一個對象
System.out.println("s3 == s4 : "+(s3==s4));
//↑false s3和s4棧區的地址不一樣,指向堆區的不一樣地址;
System.out.println("s3.equals(s4) : "+(s3.equals(s4)));
//↑true s3和s4的值相同
System.out.println("s1 == s3 : "+(s1==s3));
//↑false 存放的地區多不一樣,一個棧區,一個堆區
System.out.println("s1.equals(s3) : "+(s1.equals(s3)));
//↑true 值相同
//↑------------------------------------------------------over
/**
* 情景三:
* 因爲常量的值在編譯的時候就被肯定(優化)了。
* 在這裏,"ab"和"cd"都是常量,所以變量str1的值在編譯時就能夠肯定。
* 這行代碼編譯後的效果等同於: String str1 = "abcd";
*/
String str1 = "ab" + "cd"; //1個對象
String str11 = "abcd";
System.out.println("str1 = str11 : "+ (str1 == str11));
//↑------------------------------------------------------over
/**
* 情景四:
* 局部變量str2,str3存儲的是存儲兩個拘留字符串對象(intern字符串對象)的地址。
*
* 第三行代碼原理(str2+str3):
* 運行期JVM首先會在堆中建立一個StringBuilder類,
* 同時用str2指向的拘留字符串對象完成初始化,
* 而後調用append方法完成對str3所指向的拘留字符串的合併,
* 接着調用StringBuilder的toString()方法在堆中建立一個String對象,
* 最後將剛生成的String對象的堆地址存放在局部變量str4中。
*
* 而str5存儲的是字符串池中"abcd"所對應的拘留字符串對象的地址。
* str4與str5地址固然不同了。
*
* 內存中實際上有五個字符串對象:
* 三個拘留字符串對象、一個String對象和一個StringBuilder對象。
*/
String str2 = "ab"; //1個對象
String str3 = "cd"; //1個對象
String str4 = str2+str3;
String str5 = "abcd";
System.out.println("str4 = str5 : " + (str4==str5)); // false
//↑------------------------------------------------------over
/**
* 情景五:
* JAVA編譯器對string + 基本類型/常量 是當成常量表達式直接求值來優化的。
* 運行期的兩個string相加,會產生新的對象的,存儲在堆(heap)中
*/
String str6 = "b";
String str7 = "a" + str6;
String str67 = "ab";
System.out.println("str7 = str67 : "+ (str7 == str67));
//↑str6爲變量,在運行期纔會被解析。
final String str8 = "b";
String str9 = "a" + str8;
String str89 = "ab";
System.out.println("str9 = str89 : "+ (str9 == str89));
//↑str8爲常量變量,編譯期會被優化
//↑------------------------------------------------------over
}
}app