String直接賦值和使用new的區別


String str2 = new String("ABC");

上面語句創建了幾個字符串對象?上面語句實際上創建了2個字符串對象,一個是“ABC”這個直接量對應的對象,一個是new String()構造器返回的字符串對象。

在JVM里,考慮到垃圾回收(Garbage Collection)的方便,將heap(堆)划分為三部分:young generation(新生代)、tenured generation (old generation)(舊生代)、permanent generation(永生代)。

字符串為了解決字符串重復問題,生命周期長,存於pergmen中。

String str1 = “ABC”;可能創建一個或者不創建對象,如果”ABC”這個字符串在java String池里不存在,會在JVM的字符串池里創建一個創建一個String對象(“ABC”),然后str1指向這個內存地址,無論以后用這種方式創建多少個值為”ABC”的字符串對象,始終只有一個內存地址被分配,之后的都是String的拷貝,Java中稱為“字符串駐留”,所有的字符串常量都會在編譯之后自動地駐留。

String str2 = new String(“ABC”);至少創建一個對象,也可能兩個。因為用到new關鍵字,肯定會在heap中創建一個str2的String對象,它的value是“ABC”。同時如果這個字符串再java String池里不存在,會在java池里創建這個String對象“ABC”。

public class Test2 {
    public static void main(String[] args) {
        String s1 = new String("ABC");
        String s2 = new String("ABC");
        System.out.println(s1 == s2);//false
        System.out.println(s1.equals(s2));//true
    }
}

 

如果將一個字符串連接表達式賦給字符串變量,如果這個字符串連接表達式的值可以在編譯時就確定下來,那么JVM會在編譯時確定字符串變量的值,並讓它指向字符串池中對應的字符串。

但是如果程序使用了變量或者調用了方法,那就只有在運行時才能確定該字符串表達式的值,因此無法在編譯時確定值,無法利用JVM的字符串池。

public class Test2 {
    public static void main(String[] args) {
        String s1 = "ABCDEF";
        String s2 = "ABC" + "DEF";
        System.out.println(s1 == s2);//true,可以在編譯時確定

        String s3 = "DEF";
        String s4 = "ABC" + s3;
        System.out.println(s1 == s4);//false,無法在編譯時確定

        final String S5 = "DEF";
        String s6 = "ABC" + S5;
        System.out.println(s1 == s6);//true,使用final關鍵字,在編譯時將對S5進行宏替換
    }
}

 當程序中需要使用字符串、基本數據類型包裝實例時,應該盡量使用字符串直接量、基本數據類型的直接量,避免通過new String()、new Integer()等形式來創建字符串、基本數據類型包裝類實例,這樣能保證較好的性能。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM