1、String a = "a1";
2、String b = "a" +1:
System.out.print(a==b) //result = true ;
3、String a = "atrue" ;
4、String b = "a" + "true" ;
System.out.print(a==b) //result = true ;
分析:JVM对于字符串常量“+”连接,将程序编译期,将常量字符串的“+”连接值优化为连接后的值,拿"a" + 1来说,经编译器优化后在class中就已经是a1。在编译期其字符串常量的值就确定下来,故上面程序最终的结果都为true。
1. String a = "ab";
2. String bb = "b";
3. String b = "a" + bb;
4. System.out.println((a == b)); //result = false
分析:JVM对于字符串引用,由于在字符串的"+"连接中,有字符串引用存在,而引用的值在程序编译期是无法确定的,即"a" + bb无法被编译器优化,只有在程序运行期来动态分配并将连接后的新地址赋给b。所以上面程序的结果也就为false。
1. String a = "ab";
2. final String bb = "b";
3. String b = "a" + bb;
4. System.out.println((a == b)); //result = true
1. String a = "ab";
2. final String bb = getBB();
3. String b = "a" + bb;
4. System.out.println((a == b)); //result = false
5. private static String getBB() {
6. return "b";
7. }
分析:JVM对于字符串引用bb,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"来动态连接并分配地址为b,故上面程序的结果为false。
1. String a = "ab";
2. final String bb = getBB();
3. String b = "a" + bb;
4. System.out.println((a == b)); //result = false
5. private static String getBB() {
6. return "b";
7. }
8.
分析:JVM对于字符串引用bb,它的值在编译期无法确定,只有在程序运行期调用方法后,将方法的返回值和"a"来动态连接并分配地址为b,故上面程序的结果为false。
通过上面例子可以得出得知:
9. String s = "a" + "b" + "c";
10.
就等价于String s = "abc";
11. String a = "a";
12. String b = "b";
13. String c = "c";
14. String s = a + b + c;
15.
这个就不一样了,最终结果等于:
16. StringBuffer temp = new StringBuffer();
17. temp.append(a).append(b).append(c);
18. String s = temp.toString();
19.
由上面的分析结果,可就不难推断出String 采用连接运算符(+)效率低下原因分析,形如这样的代码:
20. public class Test {
21. public static void main(String args[]) {
22. String s = null;
23. for(int i = 0; i < 100; i++) {
24. s += "a";
25. }
26. }
27. }
28.
每做一次 + 就产生个StringBuilder对象,然后append后就扔掉。下次循环再到达时重新产生个StringBuilder对象,然后 append 字符串,如此循环直至结束。 如果我们直接采用 StringBuilder 对象进行 append 的话,我们可以节省 N - 1 次创建和销毁对象的时间。所以对于在循环中要进行字符串连接的应用,一般都是用StringBuffer或StringBulider对象来进行append操作。
分析:和上面中唯一不同的是bb字符串加了final修饰,对于final修饰的变量,它在编译时被解析为常量值的一个本地拷贝存储到自己的常量池中或嵌入到它的字节码流中。所以此时的"a" + bb和"a" + "b"效果是一样的。故上面程序的结果为true。