问题1 str1==str2 的结果是什么?
String str1 = "a" + "b" + "c";
String str2 = "abc";
System.out.println(str1 == str2);
首先字符串在常量池,并且相同的字符串只有一份。现在重点就是字符串间的+号对结果有没有影响。答案是没有。如果出现+ 左右两边都是字符串字面值的时候,此时编译期会确定整个字符串的值(直接拼接在一起)。 下图为.class文件中上述代码编译后的结果。 所以答案为true。
——————————————————————————————————————————
问题2 运行下面两行代码是,创建了几个对象?
String str2 = "abc";
String str3 = new String("abc");
答案为2个 第一行代码运行时,在字符串常量区,创建一个“abc”对象。第二行代码运行时,先在堆区开辟一个空间,创建一个String对象,然后搜寻字符串常量区有没有“abc”这个字符串,发现已经存在,则直接指向,否则创建一个新的字符串常量。
———————————————————————————————————————————
问题3 str4==str5 的结果是什么?
String str4 = new String("hello");
String str5 = new String("hello");
System.out.println(str4 == str5);
答案是 false。因为new两个对象,地址当然不一样。==当然是false。
———————————————————————————————————————————
问题4 str6==str7 的结果是什么?
public static final String a = "a";
public static final String b = "b";
String str6 = a + b;
String str7 = a + b;
System.out.println(str6 == str7);
答案为true。在编译期间如果可以确定值 此时会将变量直接替换为对应的字面值,然后问题4与问题1相同。
———————————————————————————————————————————
结论
1:创建了几个对象
A: 字面值直接赋值 此时创建的对象在字符串常量池中 这里的相同的字符串只有一份
B: 凡是new对象 都是在堆当中创建对象
2:如果出现+ 左右两边都是字符串字面值的时候,此时编译期会确定整个字符串的值(直接拼接在一起)
3:常量替换
在编译期间如果可以确定值 此时会将变量直接替换为对应的字面值