public static void main(String[] args) {
String s1 = "AB";
String s2 = new String("AB");
String s3 = "A";
String s4 = "B";
String s5 = "A" + "B";
String s6 = s3 + s4;
System.out.println(s1 == s2);
System.out.println(s1 == s5);
System.out.println(s1 == s6);
System.out.println(s1 == s6.intern());
System.out.println(s2 == s2.intern());
- 对象在堆中,字符串常量池也在堆中。
- String的"+"字符串拼接在底层创建了一个StringBuilder,用append拼接后,用toString输出。所以如果拼接很多会生成很多StringBuilder,所以效率低且大量占用堆内存。
- 当"+"两端均为编译期确定的字符串常量时,编译器会进行相应的优化,直接将两个字符串常量拼接好
试着分析如上代码:
s1:先看常量池里有没有"AB",有就直接引用,没有就在常量池里创建一个并引用。
s2:在堆中创建对象,并查看常量池中是否有"AB",没有就创建一个,有就跳过。
s3:看常量池有没有"A"有就拿来,没有就在常量池里创建一个,并引用。
s4:同上。
s5:因"+"两端皆为字符串常量,所以在编译时就已结合成一个字符串并存放入常量池。
String s0 = "ab";
final String s1 = "b";
String s2 = "a" + s1;
System.out.println((s0 == s2)); //result = true
final修饰的字符串如果能在编译时确定其值,就会优化为常量。
String s0 = "ab";
final String s1 = getS1();
String s2 = "a" + s1;
System.out.println((s0 == s2)); //result = false
public String getS1() {
return "b";
}
但如果不能在编译时确定其值,则会被当成引用,也就无法在编译时优化字符串相加。