一 点睛
拼接操作的底层其实使用了 StringBuilder
二 实战——左右两边如果是变量的字符串拼接
1 代码
@Test
public void test3() {
String s1 = "a";
String s2 = "b";
String s3 = "ab"; // 存储在堆中字符串常量池中
/*
s1 + s2 的执行细节:(变量s是临时定义的)
① StringBuilder s = new StringBuilder();
② s.append("a")
③ s.append("b")
④ s.toString() --> 约等于 new String("ab")
补充:在 jdk5.0 之后使用的是 StringBuilder,在 jdk5.0 之前使用的是 StringBuffer
*/
String s4 = s1 + s2; // 存储在堆中非字符串常量池中
System.out.println(s3 == s4); // false
}
2 图解
3 说明
s1 + s2 的执行细节
StringBuilder s = new StringBuilder();
s.append(s1);
s.append(s2);
s.toString(); // 类似于new String("ab");
4 注意
在 JDK5 之后,使用的是 StringBuilder,在 JDK5 之前使用的是 StringBuffer
三 实战——左右两边如果不是变量的字符串拼接
1 代码
/*
1. 字符串拼接操作不一定使用的是 StringBuilder!
如果拼接符号左右两边都是字符串常量或常量引用,则仍然使用编译期优化,即非 StringBuilder 的方式。
2. 针对于 final 修饰类、方法、基本数据类型、引用数据类型的量的结构时,能使用上 final 的时候建议使用上。
*/
@Test
public void test4() {
final String s1 = "a";
final String s2 = "b";
String s3 = "ab";
String s4 = s1 + s2;
System.out.println(s3 == s4); // true
}
2 说明
左右两边如果是变量的话,需要 new StringBuilder 进行拼接,但是如果使用的是 final 修饰,则是从常量池中获取。
所以说拼接符号左右两边都是字符串常量或常量引用,则仍然使用编译器优化。也就是说被 final 修饰的字符串变量,将会变成字符串常量。
在开发中,能够使用 final 的时候,建议使用上。
3 运行结果
true
四 小练习
1 代码
@Test
public void test5() {
String s1 = "javaEEhadoop";
String s2 = "javaEE";
String s3 = s2 + "hadoop";
System.out.println(s1 == s3); // false
final String s4 = "javaEE"; // s4:常量
String s5 = s4 + "hadoop";
System.out.println(s1 == s5); // true
}
2 测试
false
true