java-String詳解

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

相關文章
相關標籤/搜索