2009-12-24 104 views
12

我讀過Java中的一個String類型的對象不能改變。但是int和char變量可以。爲什麼?你可以給我一個例子嗎?字符串不能更改。但int,字符可以改變

謝謝。 (我是一個較新的-_-)

+2

你是什麼意思,不能改變?你如何給我們一個你所描述的例子的例子? – user151841 2009-12-24 02:32:15

+2

歡迎來到SO。我認爲你需要更具描述性才能得到建設性的答覆。 :) – 2009-12-24 02:33:58

+9

我不明白爲什麼這個傢伙得到一個downvote。他是一個新手,只是問一個問題。通過投票表決你讓他灰心。我看不出有什麼問題,這是一個有效的問題! – 2009-12-24 02:52:40

回答

18

正如bzabhi所說,字符串在Java中是不可變的。這意味着一個字符串對象將永遠不會改變。這並不意味着你不能改變字符串變量,只是你不能改變字符串的底層內存表示。例如:

String str = "Hello"; 
str += " World!"; 

在執行這些行之後,str將指向內存中的新字符串。原來的「你好」字符串仍然存在於內存中,但很可能它不會在那裏很長時間。假設沒有情有可原的情況,沒有東西會指向原始字符串,所以它將被垃圾收集。

我猜這是最好的方式來說,當示例的第2行執行時,內存中的一個新字符串是從原始字符串和添加到它的字符串的串聯中創建的。 str變量只是對內存位置的引用,然後被更改爲指向剛剛創建的新變量。

我對這一點並不是特別瞭解,但據我所知,這是所有「非原始」值發生的情況。任何在某種程度上來自Object的東西都遵循這些規則。原始值(如整數,布爾值,字符,浮點數和雙精度值)允許更改內存中的實際值。所以,從這個:

int num = 5; 
num += 2; 

在內存中的變化的實際值。此代碼示例不會創建新對象並更改引用,而只會更改num變量的內存值。

至於爲什麼這是真的,這只是Java製造商的設計決定。我相信有人會評論爲什麼會這樣做,但那不是我所知道的。

+0

*爲什麼?*我只是在這裏猜測,但這可能是因爲如果你要擴展一個字符串,你必須重新分配內存。字符是連續存儲的,下面的字符可能無法使用,所以它只是重新分配一塊新的內存。 – mpen 2009-12-24 03:02:10

+0

即 - 這種方法更爲高效(在大多數情況下)。除非你想分配巨大的字符串僅用於潛在的用途。但是這就是StringBuffer的用途...... – mpen 2009-12-24 03:03:12

+0

(我將'int'與'Integer'比較 - 它們的行爲非常類似,例如'AtomicInteger'和'StringBuilder'的行爲與'Integer' /'' int'和'String')。 – 2009-12-24 03:04:21

9

int和char也不能改變。與字符串一樣,您可以將不同的值放入同一個變量,但整數本身不會更改。 3將永遠是3;你不能修改它爲4.

3

我不確定是否可以顯示(通過示例)字符串不能更改。但是您可以通過閱讀Javadoc for the String class的說明部分來確認,然後閱讀方法部分並注意沒有可以更改字符串的方法。

編輯:有很多原因的字符串被設計成在Java中不可改變的。最重要的原因是不可變字符串比可變字符串更容易正確使用。如果你確實需要String的可變等價物,你可以使用StringBuilder(或StringBuffer)類。

4

字符串是不可變的類型(內部的價值也改變不了)。所有原始類型(布爾,字節,字符,短,int,long,float和double)也是如此。

int x; 
String s; 

x = 1; 
x = 2; 
s = "hello"; 
s = "world"; 
x++; // x = x + 1; 
x--; // x = x - 1; 

正如你所看到的,在任何情況下你能更改恆定值(1,2,「你好」,「世界」),但你可以改變,他們都指向(如果你扭曲你的頭腦有點並說一個int變量指向一個常量int值)。

2

值得注意的是,由於字符串是不可變的,因此如果它們被傳入方法中,則它們不能在方法內被修改,然後在方法範圍之外看到這些更改。

public void changeIt(String s) { 
    // I can't do anything to s here that changes the value 
    // original string object passed into this method 
} 

public void changeIt(SomeObject o) { 
    // if SomeObject is mutable, I can do things to it that will 
    // be visible outside of this method call 
} 
1

字符串在java中是不可變的。儘管如此,你仍然可以在字符串中附加或附加值。通過值,我的意思是原始數據類型或其他字符串。

然而,StringBuffer是可變的,即它可以在內存中更改(不必分配新的內存塊),這使得它非常有效。此外,考慮下面的例子:

StringBuffer mystringbuffer = new StringBuffer(5000); 

for (int i = 0; i<=1000; i++) 
{ 
    mystringbuffer.append ('Number ' + i + '\n'); 
} 

System.out.print (mystringbuffer); 

而不是創建千串,我們創建一個對象(mystringbuffer),它可以在長度上膨脹。我們也可以設置一個推薦的開始大小(在這個例子中是5000字節),這意味着當一個新字符串被追加時,緩衝區不必連續地請求內存。

雖然StringBuffer不會在任何情況下提高效率,但如果您的應用程序使用長度增長的字符串,則效率會很高。代碼也可以使用StringBuffer更清晰,因爲append方法可以使您不必使用長分配語句。