2011-06-03 38 views
2

可能重複:
difference between string object and string literalDIFF在Java中打賭新的String( 「XYZ」)和 「XYZ」

你好,

最重要的,讓我們拿出了Java的事實帶字符串

字符串不可變 我的問題 - 如果字符串是不可變的,那麼下面的語句應該有編譯錯誤!

   String str = "xyz"; 
        or 
      String str = new String("xyz"); 

      str = "abc";  //COMPILATION ERROR 
       or 
      str = new String("abc"); //COMPILATION ERROR 

下面的實例有什麼區別?

String str = "xyz"; 
     and 
String str = new String("xyz"); 

阿米特。

+1

只是一個提示:字符串值是不可變的,而不是包含變量。 – 2011-06-03 09:31:19

回答

5

字符串是不可變的,意味着你不能做類似str[1] = 'x'的事情,即你不能改變字符串的內容。

This會回答你的第二個問題。

+0

str [1]是字符串數組。如果我只是聲明String str =「xyz」 – 2011-06-03 09:29:46

+0

@Amit:String只是一個字符數組,但我怎麼能像上面的語句一樣寫。所以,你不能替換String的內部內容,因爲字符串是不可變的。 – 2011-06-03 09:33:35

3

字符串是不可變的,所以你不能改變字符串的內容。

在下面的代碼:

String str = "xyz"; 
str = "abc"; 

你不改變String實例的內容,但對變量str而分配一個新的String實例。也就是說,如果你這樣做:

String str = "xyz"; 
String otherStr = str; 
String str = "abc"; 

然後otherStr將保持不變。所以你實際上並沒有改變str指向的對象。

關於你的第二個問題

String str = "xyz"; 

取一個String對象從字符串池值"xyz",而

String str = new String("xyz"); 

實例化一個新的對象。

也就是說,如果你做

String a = "xyz", b = "xyz"; 

,你將有a == b,而如果你做

String a = new String("xyz"), b = new String("xyz"); 

這會不會是這種情況。example

欲瞭解更多信息,請參見:

1

如果字符串是不可變的那麼下面 語句應該具有編譯 錯誤!

您誤解了不變性概念。看看Prasoon的回答。
字符串不可變性意味着你不能改變字符串內的內容。

String a = "hello"; 
String b = "hello";  
System.out.println(a==b); // returns true. 

這裏既有ab兩個字符串引用相同的對象。


是哪兩個 實例之間的區別?

String a = "hello"; 
String b = "hello"; 
System.out.println(a==b); // returns true. 

都指向同一個字符串文字。

String a = new String("hello"); 
String b = new String("hello"); 
System.out.println(a==b); // returns false. 

創建了兩個不同的字符串對象。

0
String str = "xyz"; 

是內部緩存的字符串實例。

String str = new String("xyz"); 

是無法從緩存

由於側事實注意到以下行爲實例化一個新的對象......

"xyz" == "xyz" evals true 

new String("xyz") == new String("xyz") evals false 

new String("xyz").equals(new String("xyz")) evals true 

公告同時在Java中==比較對象的引用。

+0

你能解釋我爲什麼它返回true()與equals()嗎? – 2011-06-03 09:41:02

+0

'equals'實現字符串內容比較,在這種情況下是true。 '=='將測試對象內存引用的等同性,當從緩存中重用實例時,該引用將爲true。 – 2011-06-03 09:49:52

2

字符串是不可變的。字符串參考文獻沒有。這是區別。

所以:

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(檢查引用匹配,而不是字符串是否)將是真實的,因爲文字字符串是interneda == c保證是錯誤的,因爲我們使用了c的構造函數。 a.equals(b)a.equals(c)都將爲真,因爲a,bc都指代equivalent個字符串。

+0

@Crowder;這是關於'Blech,重複'假設我有2個類A和B,並且在B構造函數中我傳遞了A的引用;通常我們寫了一個代碼A a;//聲明一個全局變量,並在構造函數中簡單地寫this.a = $ {傳遞引用}我的意思是說,我們不使用新的運算符....你能詳細說明它和(2)我怎麼能我自己的類是不可變的? – 2011-06-03 14:18:05

+0

@Amit:這聽起來像是一個笑話,但它不是:爲了讓你自己的類不可變,不要提供任何mutator函數。例如,如果'A'接受'foo'和'bar'作爲構造函數參數,並通過'getFoo'和'getBar'方法使它們可用,*不提供'setFoo'和'setBar'突變體方法。然後確保1)你在構造函數中接受的東西是不可變的(在這種情況下,你可以使用給定的引用,就像你現在所做的那樣),或者2)如果你接受任何可變的東西, *複製*以供自己使用,所以沒有任何東西可以改變你的副本。 – 2011-06-03 17:00:04

相關問題