String s=new String("xyz");建立幾個String對象的問題

首先讓咱們瞭解幾個概念:線程

棧 :由JVM分配區域,用於保存線程執行的動做和數據引用。對象

堆 :由JVM分配的,用於存儲對象等數據的區域。內存

常量池constant pool :在堆中分配出來的一塊存儲區域,用於存儲顯式 的String,float或者integer.這是一個特殊的共享區域,能夠在內存中共享的不常常改變的東西,均可以放在這裏。字符串

進入正題:原理

String a = "abc";①
String b = "abc";②引用

使用String a = "abc";的方式,能夠在必定程度上提升程序的運行速度,由於JVM會自動根據棧中數據的實際狀況來決定是否有必要建立新對象。
①代碼執行後在Constant Pool中建立了一個值爲abc的String對象,②執行時,由於Constant Pool中存在"abc"因此就不在建立新的String對象了。float

String   c   =   new   String("xyz");①
String   d   =   new   String("xyz");②程序

讓咱們來看看這兩句代碼在內存中發生了什麼,①Class被CLassLoader加載時,你的"xyz"被做爲常量讀入,在constant   pool裏建立了一個共享的"xyz",而後當調用到new   String("xyz")的時候,會在heap裏建立這個new   String("xyz");②因爲constant   pool中存在"xyz"因此再也不建立"xyz",而後建立新的new   String("xyz")。
對於String c = new String("xyz");的代碼,與String a = "abc"不一樣的是一律在堆中建立新對象,無論其字符串值是否相等,是否有必要建立新對象,從而加劇了程序的負擔。
程序1
String   s1   =   new   String("xyz");     //建立二個對象,一個引用
String   s2   =   new   String("xyz");     //建立一個對象,而且之後每執行一次建立一個對象,一個引用
程序2
String   s3   =   "xyz";     //建立一個對象,一個引用  
String   s4   =   "xyz";     //不建立對象,只是建立一個新的引用方法

重要的是理解constant pool與new關鍵字數據

當調用 intern 方法時,若是池已經包含一個等於此 String 對象的字符串(該對象由 equals(Object) 方法肯定),則返回池中的字符串。不然,將此 String 對象添加到池中,而且返回此 String 對象的引用。(不管怎樣都返回池中的對象)

下面的這個例子能幫助咱們更深刻的理解String的存儲和賦值原理

String str1 = new String("123");
        String str2 = "123"; 
        String str3 = str1.intern(); 
        System.out.println((str1 == str2) +","+ (str3 == str2));

        輸出 false,true        
        String str4 = new String("234");
        String str5 = new String("234");    
        String str6 = str4.intern();
        String str7 = str5.intern();   
        System.out.println((str4 == str5) +","+ (str6 == str7));

        輸出 false,true

相關文章
相關標籤/搜索