public class Str {
//测试环境jdk1.8
//参考:https://www.jianshu.com/p/d5ecfceccccd
public static void main(String[] args){
char[] c = {'a','b','c'};
String s = new String(c); //生成2哥对象分别存放在堆空间,常量池
String str = "aaa"; //常量池里
str = "abc";
//jdk7以上
String str1 = new String("1")+new String("2");//生成了3个对象, 常量池中对象"1"和"2",堆中的字符串对象"12"
str1.intern(); //jdk1.7中,在常量池中找不到对象"12",所以会在常量池生成一个引用,指向堆中的字符串对象"12"
String str2 = "12";//直接在常量池中生成"12"对象,由于在常量池中有这么一个引用,指向堆中的字符串对象"12",所以将这个引用给str2,而不会再在常量池中生成"12"对象了。
System.out.println(str2==str1);//所以str1和str2是指向同一个对象,jdk1.7中返回true
//jdk6
String str11 = new String("11")+new String("22");//生成了3个对象, 常量池中对象"11"和"22",堆中的字符串对象"1122"
str11.intern(); //jdk1.6会在常量池生成一个字符串对象"1122"
String str22 = "1122";//str1指向常量池字符串对象"1122"
System.out.println(str22==str11);//由于str2和str1指向不同,jdk1.6中返回false
//jdk7
String str3 = new String("3")+new String("4");//生成了3个对象, 常量池中对象"3"和"4",堆中的字符串对象"34"
String str4 = "34";//直接在常量池中生成"34"对象
str3 = str3.intern(); //在常量池中已经有对象"34"了,返回常量池中"34"对象的引用
System.out.println(str3==str4);//true
String str5 = new String("5");//生成了2个对象, 常量池中对象"5",堆中的字符串对象"5"
str5 = str5.intern();//在常量池中已经有对象"5"了,返回常量池中"5"对象的引用
String str6 = "5";//直接指向常量池中已有的"5"对象
System.out.println(str5==str6);//true
String str7 = new String("7");
System.out.println(str7.intern() == str7);//str7.intern()指向了常量池中的"7"对象,str7指向了堆,所以返回false
String str8=new String("8") + new String("9");//生成了3个对象,常量池中对象"8"和"9",堆中的字符串对象"89"
System.out.println(str8.intern() == str8);//str8.intern(),"89"在常量池中不存在, 所以会返回89的引用 //true
String str9 = new String("10") + new String("11");
String str10 = new String(str9);//堆里创建str10对象
System.out.println(str10.intern() == str10);//堆中str10的引用返回//true
// System.out.println(str9.intern() == str9);//str9.intern()返回堆中str10的引用//false
System.out.println(str9.intern() == str10);//str9.intern()返回堆中str10的引用//true
String s1 = "ab";
String s2 = "a";
String s3 = "b";
String s4 = s2 + s3;
System.out.println(s1 == s4);//输出false,因为s2+s3实际上是使用StringBuilder.append来完成,会生成不同的对象。
String s5 = "cd";
final String s6 = "c";
final String s7 = "d";
String s8 = s6 + s7;
System.out.println(s5 == s8);//输出true,因为final变量在编译后会直接替换成对应的值,所以实际上等于s8="c"+"d",而这种情况下,编译器会直接合并为s8="cd"。
}
}