java常量池技術
java中的常量池技術,是為了方便快捷地創建某些對象而出現的,當需要一個對象時,就可以從池中取一個出來(如果池中沒有則創建一個),則在需要重復創建相等變量時節省了很多時間。常量池其實也就是一個內存空間,常量池存在於方法區中。
JVM的編譯器將源程序編譯成class文件后,會用一部分字節分類存儲這些粗體代碼。而這些字節我們就稱為常量池。其中包括了關於類,方法,接口等中的常量,也包括字符串常量,如String s ="java"這種申明方式;對於String s = "java",在編譯成.class時能夠識別為同一字符串的,自動優化成常量,所以如果有多個字符串"java",則它們都會引用自同一String對象。也就是說String s = "java" 其中"java"值在JAVA程序編譯期就確定下來了的。(大家可以用UE編輯器或其它文本編輯工具在打開class文件后的字節碼文件中看到這個java值)。這個java存在在常量池中。注意:常量池只存儲文字字符串值,不存儲符號引用。
而在運行時創建的字符串具有獨立的內存地址,所以不引用自同一String對象.String的intern()方法會查找在常量池中是否存在一份equal相等的字符串,如果有則返回一個引用,沒有則添加自己的字符串進入常量池,注意:只是字符串部分。所以這時會存在2份拷貝,常量池的部分被String類私有並管理,自己的那份按對象生命周期繼續使用。String s = new String("java");語句,到底創建了幾個對象呢? "java"本身就是常量池中的一個對象,而在運行時執行new String()時,將常量池中的對象復制一份放到堆中,並且把堆中的這個對象的引用交給s持有。所以這條語句就創建了2個String對象。
String類也是java中用得多的類,同樣為了創建String對象的方便,也實現了常量池的技術。
測試代碼如下:
public class Test{
public static void main(String[] args){
//s1,s2分別位於堆中不同空間
String s1=new String("hello");
String s2=new String("hello");
System.out.println(s1==s2);//輸出false
//s3,s4位於池中同一空間
String s3="hello" Strings4="hello";
System.out.println(s3==s4);//輸出true
}
}
用new String()創建的字符串不是常量,不能在編譯期就確定,所以new String()創建的字符串不放入常量池中,他們有自己的地址空間。
String 對象(內存)的不變性機制會使修改String字符串時,產生大量的對象,因為每次改變字符串,都會生成一個新的String。 java 為了更有效的使用內存,常量池在編譯期遇見String 字符串時,它會檢查該池內是否已經存在相同的String 字符串,如果找到,就把新變量的引用指向現有的字符串對象,不創建任何新的String 常量對象,沒找到再創建新的。所以對一個字符串對象的任何修改,都會產生一個新的字符串對象,原來的依然存在,等待垃圾回收。
代碼:
String a = “test”;
String b = “test”;
String b = b+"java";
a,b同時指向常量池中的常量值"text",b=b+"java"之后,b原先指向一個常量,內容為"test”,通過對b進行+"java"操作后,b之前所指向的那個值沒有改變,但此時b不指向原來那個變量值了,而指向了另一個String變量,內容為”text java“。原來那個變量還存在於內存之中,只是b這個變量不再指向它了。
八種基本類型的包裝類和對象池 java中基本類型的包裝類的大部分都實現了常量池技術,這些類是Byte,Short,Integer,Long,Character,Boolean,另外兩種浮點數類型的包裝類則沒有實現。另外Byte,Short,Integer,Long,Character這5種整型的包裝類也只是在對應值小於等於127時才可使用常量池
Integer a = new Integer(128);
Integer b = new Integer(128);
這個時候再問你,輸出結果是什么?你就知道是false了。如果把這個數換成127,再執行:
Integer a = 127;
Integer b = 127;
System.out.println(a == b);
結果就是:true
進行對象比較時最好還是使用equals,便於按照自己的目的進行控制。這里引出equals()和==,equals比較的是字符串字面值即比較內容,==比較引用。