首先看一個程序
package reverse; public class Reverse { public static void main(String[] args) { String c1=new String("abc"); String c2=new String("abc"); String c3=c1; System.out.println("c1==c2:"+ (c1==c2)); System.out.println("c1.equals(c2):"+c1.equals(c2)); System.out.println("c3==c1:"+(c3==c1)); System.out.println("c1.equals(c3):"+c1.equals(c3)); c1="han"; System.out.println(c1+" "+c3); System.out.println(""+(c3==c1)); } }
第一個輸出語句c1==c2很好理解,因為c1和c2都是用new 創建的對象的引用,雖然對象的值相同,但兩個對象在不同的內存空間,也就是說c1和c2是對兩個不同的對象的引用,所以結果為false。第二個輸出語句c1.equals(c2)是調用了String類的equals方法,該方法用於比較兩個字符串對象的值是否相等,所以結果為true。
c1、c2變量在內存中的模擬:
對於c3==c1為true是因為將c1賦值給了c3 也就是將c1對象的引用賦值給了c3;c1和c3在內存中的模擬:
對於System.out.println(c1+" "+c3),這個輸出語句有人會問既然c1和c3引用的是同一個對象,為什么改變c1的值c3的值並不會改變呢?
這就涉及到了Java中String對象的不可變性,什么叫不可變性呢,簡單的說就是一旦一個String對象被創建並被賦值(初始化)這個對象的值就不會變化。
一旦一個String對象在內存中創建,它將是不可改變的,所有的String類中方法並不是改變String對象自己,而是重新創建一個新的String對象。
也就是說c1=han,並不是改變了原有對象的值,而是創建了一個新的字符串對象,這個對象的值是han,並把這個對象的引用賦值給了c1。
此時c1 和c3在內存中的模擬:
所以此時c1==c3 為false
正因為String對象的不可變性,如果需要對字符串進行大量的修改、添加字符、刪除字符等操作盡量不要使用String對象,因為這樣會頻繁的創建新的對象導致程序的執行效率下降
這時我們可以使用字符串生成器StringBuilder。