字符串是不可變的。字符串參考文獻沒有。這是區別。
所以:
String str = "abc";
str
是一個變量,指的是一個不可改變的字符串 「abc」。現在,如果我做的:
str = "def";
str
仍然是一個變量,指的是不同的不可變的字符串(「高清」)。我可以改變什麼str
指向所有我想要的,str
是變量。我無法更改任何字符串的實際內容(因爲Java的字符串是不可變的,通過設計)。每當你做一些似乎修改字符串的東西時(比如toUpperCase
),它實際上做的是創建一個新的字符串,其中包含舊字符串內容的副本,並按照上述方式進行修改。
使字符串不可改變的一點是,我知道如果我有一個字符串的引用,該字符串永遠不會改變。在傳遞字符串時這是一個非常有用的保證。如果我們沒有這個保證,我們會一直在複製字符串,只是爲了保護我們免受修改它們的人的影響。例如,考慮一個標準的制定者功能的name
屬性:
void setName(String n) {
this.name = n;
}
如果字符串不是一成不變的,我們不得不這樣做:
void setName(String n) {
this.name = new String(n); // Blech, duplication
}
...所以我們知道我們的字符串的副本不會以我們不期望的方式改變。這會導致內存中字符串數據的重複,其中大部分是不必要的,所以Java的設計者非常聰明地決定字符串是不可變的,並且您可能想要的任何更改都會創建一個新字符串而不是修改舊的一個就地。 (你可以爲那些真正使用char[]
,而不是保證它的情況下修改就地行爲。)
關於你提到的有關str = "abc";
和str = new String("abc")
之間的差別單獨的問題,不同的是後者(使用constructor)保證返回一個新的參考,而前者不是。例如: -
String a = "abc";
String b = "abc";
String c = new String("abc");
a == b
(檢查引用匹配,而不是字符串是否)將是真實的,因爲文字字符串是interned。 a == c
保證是錯誤的,因爲我們使用了c
的構造函數。 a.equals(b)
和a.equals(c)
都將爲真,因爲a
,b
和c
都指代equivalent個字符串。
只是一個提示:字符串值是不可變的,而不是包含變量。 – 2011-06-03 09:31:19