Java中存在常量池用来存放字符串等数据常量,从而反映出字符串的不变性。
简单来说,字符串一经确定就不可改变。
如
String s1 = "abc";
s1 += "def";
System.out.println(s1); //输出abcdef
事实上这段代码产生了3段字符串空间,一开始分配的"abc",第二句分配了一个"def"空间,第三句又开辟了一个新的空间,存进去了"abcdef",最后将s1的指针指到了新分配的空间上,完成了"abc"+"def".
试分析以下 demo
// demo1
String str1 = "java";
String str2 = "java";
System.out.println(str1 == str2);//true
/** 在常量池中str1和str2指向同一个字符串 */
// demo2
String str1 = new String("java");
String str2 = new String("java");
System.out.println(str1 == str2);//false
/** str是在堆中定义的,所以肯定不等 */
// demo3
String str1 = "java";
String str2 = "blog";
String s = str1+str2;
System.out.println(s == "javablog");//false
/** s和"javablog"地址不等 */
// demo4
String s = "java"+"blog";
System.out.println(s == "javablog");//true
/** 两个常量相加在常量池中地址相等 */
// demo5
String str2 = "blog";
String s = "java" + str2;
System.out.println(s == "javablog");// false
/** 理由同demo3 */
Java中对不变性的解决方案
提供了StringBuilder和StringBuffer两种类来进行字符串处理.
两者基本是相同的,唯一的区别在于StringBuffer是线程安全的,而StringBuilder线程安全无法保证,不保证同步。但是StringBuffer相对StringBuilder效率要差一点。
StringBuilder s = new StringBuilder();
s.append("aaa");//append不断向里放字符串
s.append(“bbb”);
String result = s.toString();
System.out.println(result);//输出aaabbb