1.6.1 拼接结果的存储和比较问题
原则:
示例:
package com.github.string.demo7;
/**
* @author maxiaoke.com
* @version 1.0
*
*/
public class Test {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
String s4 = (s1 + "world").intern(); // 将拼接的结果放在常量池中
String s5 = (s1 + s2).intern();
System.out.println(s3 == s4); // true
System.out.println(s3 == s5); // true
}
}
package com.github.string.demo8;
/**
* @author maxiaoke.com
* @version 1.0
*
*/
public class Test {
public static void main(String[] args) {
final String s1 = "hello";
final String s2 = "world";
String s3 = "helloworld";
String s4 = s1 + "world"; // s1是常量,"world"也是常量,所以s4是常量
String s5 = s1 + s2; // s1是常量,s2是常量,所以s5是常量
String s6 = "hello" + "world"; // "hello"是常量,"world"是常量,所以s6是常量
System.out.println(s3 == s4); // true
System.out.println(s3 == s5); // true
System.out.println(s3 == s6); // true
}
}
package com.github.string.demo9;
/**
* @author maxiaoke.com
* @version 1.0
*
*/
public class Test {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
String s4 = s1 + "world"; // s1是变量,"world"是常量,所以s4是变量
String s5 = s1 + s2; // s1是变量,s2是变量,所以s5是变量
String s6 = "hello" + "world"; // "hello"是常量,"world"是常量,所以s6是常量
System.out.println(s3 == s4); // false
System.out.println(s3 == s5); // false
System.out.println(s3 == s6); // true
}
}
1.6.2 拼接效率问题
package com.github.string.demo10;
/**
* @author maxiaoke.com
* @version 1.0
*
*/
public class Test {
public static void main(String[] args) {
String str = "0";
for (int i = 0; i < 5; i++) {
str += i;
}
System.out.println("str = " + str);
}
}
不过,现在的 JDK 版本,都会使用可变字符序列对如上的代码优化,不信,反编译查看字节码:
javap -c Test.class
Compiled from "Test.java"
public class com.github.string.demo10.Test {
public com.github.string.demo10.Test();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: ldc #2 // String 0
2: astore_1
3: iconst_0
4: istore_2
5: iload_2
6: iconst_5
7: if_icmpge 35
10: new #3 // class java/lang/StringBuilder
13: dup
14: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
17: aload_1
18: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
21: iload_2
22: invokevirtual #6 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
25: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
28: astore_1
29: iinc 2, 1
32: goto 5
35: getstatic #8 // Field java/lang/System.out:Ljava/io/PrintStream;
38: new #3 // class java/lang/StringBuilder
41: dup
42: invokespecial #4 // Method java/lang/StringBuilder."<init>":()V
45: ldc #9 // String str =
47: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
50: aload_1
51: invokevirtual #5 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
54: invokevirtual #7 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
57: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V
60: return
}
1.6.3 concat 方法拼接
concat() 方法拼接,哪怕是两个常量对象拼接,结果也是在堆中。
示例:
package com.github.string.demo19;
/**
* @author maxiaoke.com
* @version 1.0
*
*/
public class Test {
public static void main(String[] args) {
String s1 = "hello";
String s2 = "world";
String s3 = "helloworld";
String s4 = "hello".concat("world");
String s5 = "hello" + "world";
System.out.println(s3 == s4); // false
System.out.println(s3 == s5); // true
System.out.println(s1 + s2 == s5); // false
}
}