package com.wangzhu.string; /** * String類是final類,也就是說String類不能被繼承,並且其成員方法都預設為final方法。<br/> * * * @author wangzhu * @date 2015-2-1下午5:42:19 * */ public class StringDemo1 { public static void main(String[] args) { String str = ""; for (int i = 0; i < 10000; i++) { str += "test"; } } }
使用命令反編譯位元組碼:javap -c StringDemo1
從上可知,在行8處建立了一個StringBuilder物件,並且每次迴圈都會重新建立一個StringBuilder物件。
備註:行8到35是迴圈部分。
package com.wangzhu.string; /** * 內容可以進行修改,並且其並沒有重寫equals與hashcode方法<br/> * * @author wangzhu * @date 2015-2-1下午5:49:02 * */ public class StringBuilderDemo1 { public static void main(String[] args) { StringBuilder accum = new StringBuilder(); for (int i = 0; i < 10000; i++) { accum.append("test"); } } }
使用命令反編譯位元組碼:javap -c StringDemo1
從上可知,只建立了一個StringBuilder物件。備註:行13到27是迴圈部分。
結論:StringBuilder的例子中,從頭到尾只建立了一個StringBuilder物件,而String的例子中,每一次迴圈中都建立了一個StringBuilder物件,故String的效率低於StringBuilder。
其他:
package com.wangzhu.string; public class StringDemo2 { /** * @param args */ public static void main(String[] args) { String str1 = "a1"; String str2 = "a" + 1; System.out.println(str1 == str2);// true /** * 分析:在程式編譯期間,JVM就將字串常量的+連線優化為連線後的值。即在編譯期字串常量的值就確定下來了。<br/> */ String str21 = "ab"; String str22 = "b"; String str23 = "a" + str22; System.out.println(str21 == str23);// false /** * 分析:JVM對於字串引用,由於在字串的+連線中,有字串引用的存在,故引用的值在程式編譯期無法確定,<br/> * 只有在程式執行期來動態分配並將連線後的新地址賦給變數。 */ String str31 = "ab"; final String str32 = "b"; String str33 = "a" + str32; System.out.println(str31 == str33);// true /** * 分析:對於final修飾的變數,其在編譯時被解析為常量值的一個本地拷貝儲存到自己的常量池中或嵌入到其位元組碼流中。<br/> */ System.out.println(str21 == str23.intern());// true /** * 分析:使用String的intern方法,會返回該字串在常量池中的地址值。<br/> */ } }