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

相关文章
相关标签/搜索