您的位置:首页 > 编程语言 > Java开发

java字符串

2016-04-26 00:00 274 查看
结构图:



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 :
结构图:



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:
结构图:



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 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的值
第二点:

在jdk6中String常量池是放在perm中,而jdk7中常量池是放在堆中。GC在进行Full GC(不经常触发)才会回收perm的内存空间,但是堆的回收(特指年轻代)却是比较经常发生的
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: