Java字符串
Java字符串是不可变的,也就是说不能对字符串更改,跟字符数组是不同的。
Java字符串内存管理
Java字符串可能存在于两个地方,第一个是编译时已经存在的常量池,另外一个是运行时动态管理的字符串池。
String str1="abc";
String str2=new String("abc");
String str3=new String("abcd");
String str4=str2.intern();
String str5=str3.intern();
String str6="ab"+"c";
常量池维护的字符串常量很容易理解,就是上述代码中双引号中的字面值。str6
比较特殊,它也是维护在常量池中的,编译器在编译时进行优化,拼接了ab和c。
动态创建的,例如new出来的字符串由字符串池维护。
intern
方法说的是如果该字符串已经在常量池中存在(字符串内容相等),则返回在常量池中的引用。
str1
引用的是常量池中的"abc",而str2
引用的堆中字符串池中的"abc"。
str2.intern()
表示如果常量池中存在"abc",则返回常量池中的该字符串引用,所以str1
和str4
是相等的。
str6
也是引用常量池中的"abc",所以跟str1
也是相等的。
对以上内容画一个简单图示:
问题
String str1="abcdef";
String str2="abcdef";
System.out.println(str1==str2);
String str3="abc"+"def";
System.out.println(str1==str3);
String str4=new String("abcdef");
String str5=new String("abcdef");
System.out.println(str4==str5);
System.out.println(str1==str4);
System.out.println(str1==str4.intern());
上述代码的输出结果是:
true
true
false
false
true
总结
字符串存储在常量池和堆字符串池中。
常量池中不可能存在相同的字符串,堆字符串池中可能存在相同的字符串(以相同字面值new出来的不同字符串对象)。
判断两个引用指向的字符串对象是否相同,分清楚字符串对象是在常量池还是在堆字符串池中即可。