String类创建的时候的内存图:(结合代码)
/**
*
*/
/**
* @author fshxxxyydys
*
*/
public class StringInvariance {
/**
* @param args
*/
public static void main(String[] args) {
String str1 = new String( "fshxxxyydys");
String str2 = new String( "fshxxxyydys");
System.out.println(str1 == str2);
//只有str1和str2指向同一个对象的时候才能相等
//用new暗示系统为新的对象开辟一个新的空间
//此时即使内存(堆)中已经存在了一个一样的对象
//系统也不会将新的引用变量(指针)指向它,而是为新的对象开辟
//一块新的内存空间,所以此时str1和str2不相等
System.out.println(str1.equals(str2));
//比较两个引用变量指向的对象的内容是否相等
String c1 = "fshxxxyydys";
String c2 = "fshxxxyydys";
System.out.println(c1 == c2);
//java中字符串使用频繁,为了提高效率,系统会将字符串进行缓存与复用
//JAVA的字符串对象一旦被创建,不能修改,这种语法现象叫做
//字符串的不变性(immutable String),在系统创建c2时,发现内存中已经
//存在了一个“fshxxxyydys”对象,而且没有收到要为新对象创建新的内存
//的暗示“new”使用就直接将c2指向了系统已经存在的“fshxxxyydys”对象
//所以此时才c1和c2相等
c1 = c1.replace("x","O");
System.out.println("c1="+ c1);
System.out.println("c2="+c2);
//java中一旦字符串确定,就不能修改,对任何字符串的修改
//操作,最终都会产生新的字符串对象
//以上操作中c1的指针被指向一个新的对象“fshOOOyydys”
//因此此时c1和c2将不再相等
System.out.println(c1 == c2);
//由于每次产生新的对象,所以如果进行大量的String操作内存会很快的
//消耗殆尽,JVM GC 要一直的工作,导致性能下降,如果有涉及到较多的字符串相加操作,
//请使用StringBuffer类。
//StringBuffer是线程安全的,速度较慢,如果你确定你的程序不需要线程安全
//建议使用StringBuilder,其实StringBuffer的兄弟类,拥有完全一致的API,但是速度较快。
StringBuffer strbf = new StringBuffer();
strbf.append("fshx") //此函数返回的是strbf本身所以可以连续追加
.append("xx")
.append("yydys")
.append(888888)
.append(true);
System.out.println(strbf.toString());
}
}
=======================================================================
Result:
false
true
true
c1=fshOOOyydys
c2=fshxxxyydys
false
fshxxxyydys888888true
=========================================================================