java之String類詳解

Java運行時會維護一個String Pool(String池),用來存放運行時中產生的各種字符串,池中的字符串的內容不重複。而一般對象不存在這個緩衝池,創建的對象僅僅存在於方法的堆棧區。String s1="abc";和String s2="abc"; 第一句的是在String池中創建一個對象”abc”,然後引用時s1指向池中的對象”abc,第二句執行時,因爲”abc”已經存在於String池了,所以不再創建,直接指向,僅創建了1個對象。String s=new String("abc");是在堆內存上創建一個String對象,內容是”abc”,s指向堆內存對象的首地址,因此並不一樣。 




注意:
String a=new String("hawk");//一個是生成實例對象//這個實在堆得內存上創建一個String對象.


String s="abc";//一個是生成引用//這樣聲明的字符串會放在字符串的緩衝池中,當然只是String特有的緩衝池,一般引用對象和基本數據類型對象都沒有,




//它是java中唯一不需要new 就可以產生對象的途徑


///s = "Initial Value";
s = new String("Initial Value");
對於字符串常量,如果內容相同,Java認爲它們代表同一個String對象。而用關鍵字new調用構造器,總是會創建一個新的對象,無論內容是否相同。
不可變類有一些優點,比如因爲它的對象是隻讀的,所以多線程併發訪問也不會有任何問題


你獲得這個類的一個實例引用時,你不可以改變這個實例的內容。不可變類的實例一但創建,其內在成員變量的值就不能被修改


堆包含方法區和new出來的對象,而常量池在方法區裏,兩個也是有聯繫的,
那樣的字符串常量就是存放在常量池的,通過new 出來的字符串對象就是存在於堆空間裏的,stringBuffer纔是新建存在於緩衝區的字符串對象




String類型可以對字符串常量直接相加的表達式進行優化,這說明javac編譯可以對字符串常量直接相加的表達式進行優化,不必要等到運行期去進行加法運算處理,而是在編譯時去掉其中的加號,直接將其編譯成一個這些常量相連的結果。

補充:String的intern使用

存在於.class文件中的常量池,在運行期被JVM裝載,並且可以擴充。String的intern()方法就是擴充常量池的 一個方法;
當一個String實例str調用intern()方法時,Java查找常量池中是否有相同Unicode的字符串常量,如果有,則返回其的引用,
如果沒有,則在常量池中增加一個Unicode等於str的字符串並返回它的引用

String s0= "kvill"; 
String s1=new String("kvill"); 
String s2=new String("kvill"); 
System.out.println( s0==s1 ); 
System.out.println( "**********" ); 
s1.intern(); 
s2=s2.intern(); //把常量池中"kvill"的引用賦給s2 
System.out.println( s0==s1); 
System.out.println( s0==s1.intern() ); 
System.out.println( s0==s2 ); 
結果爲: 
false 
********** 
false //雖然執行了s1.intern(),但它的返回值沒有賦給s1 
true //說明s1.intern()返回的是常量池中"kvill"的引用 
true 

說明用intern的方法必須重新把引用賦值給string對象的引用,這樣纔可以賦值引用成功.

intern的作用是在字符串運行期間,在.class文件中添加常量



有什麼不對的地方,歡迎大家給提意見.






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章