java字符串

結構圖:
java

public static void test1() {
	String str1 = "abc";
	String str2 = "abc";
	System.out.println(str1==str2);
	System.out.println(str1==str2.intern());
	System.out.println(str1.intern()==str2.intern());
}

結果:true,true,true
數組

例2 :
結構圖:
spa

public static void test1() {
	String str1 = "abc";
	String str2 = new String("abc");
	System.out.println(str1==str2);
	System.out.println(str1==str2.intern());
	System.out.println(str1.intern()==str2.intern());
}
結果:false,true,true

例3:
結構圖:
code

public static void test3() {
	String str1 = new String("abc");
	String str2 = new String("abc");
	System.out.println(str1==str2);
	System.out.println(str1==str2.intern());
	System.out.println(str1.intern()==str2.intern());
}

結果:false,false,true 對象

結果說明
若是變量直接引用常量池的字符串,那麼結果就會一致。但若是變量引用對象是一個字符串實例,而該實例纔去引用常量池的字符串,那麼比較的結果就不一致。而使用方法intern,就是去取得常量池中的引用

擴展:---------------------------------- 內存

第一點: 字符串

在jdk6中,字符串由三部分組成:char[] , offset , count。由於這樣的結構致使在使用String.substring這個方法時可能發生內存泄漏例: string

String str1 = "abcd...."  
//假設str1有1萬個字符,同時char[]的長度也有1萬
String str2 = str1.substring(0,1)  
//str2只想要一個字符,但substring方法並無建立出一個新的字符串常量,
//只是在str1基礎上改變了它的偏移量,這彷佛看起來很不錯,由於str1與str2共用char[]節約了內存。
str1 = null;
//這時釋放了str1,可是str1的實例並不會被GC回收,由於str2佔有着它,而str2理論上
//應該只有1字符大小的空間,但實際不是,它佔着一萬個字符大小的內存.
而在jdk7中它的結構變了,去掉了offset 與count 兩項,String內容由char[]決定,而數組自己也表明了String的值

第二點: class

在jdk6中String常量池是放在perm中,而jdk7中常量池是放在堆中。GC在進行Full GC(不常常觸發)纔會回收perm的內存空間,可是堆的回收(特指年輕代)倒是比較常常發生的 
                                                 test

相關文章
相關標籤/搜索