2013-12-16 27 views
0

由於字符串是不可變的,所以我必須按如下方式編寫以從str中刪除所有非alphanemeric。Java String如何在內部刪除所有非數字作品?

void test(String str) { 
    str = str.replaceAll("[^a-zA-Z0-9\\s]", "").toLowerCase(); 
    System.out.println("\n" +str); 
    } 

我不明白的是,如何通過重新分配給str來工作?由於字符串是不可變的,我明白,如果我將它分配給一個新的字符串newString,他們指出兩個不同的對象,str和newString。 它,原始字符串指向str和修改後的字符串指向具有兩個不同的不可變字符串的newStr。這對我來說很好。

void test(String str) { 
      String newStr = str.replaceAll("[^a-zA-Z0-9\\s]", "").toLowerCase(); 
    System.out.println("\n" +newStr); 
    } 

但是,如何通過重新分配到相同的str對象來工作?根據我的理解,它不應該工作,因爲immutable str不能修改,所以修改後的str的結果不能存儲在不可變的str中。

void test(String str) { 
     // this shouldn't be working based on my understanding. But it works. Why? 
    str = str.replaceAll("[^a-zA-Z0-9\\s]", "").toLowerCase(); 
    System.out.println("\n" +str); 
    } 

正如你所看到下面的圖片,字符串1和字符串都指向堆中同一個String對象。你能否澄清這是如何在內部工作的?

+0

那麼它只是簡單地將引用('str')切換到新創建的'String'對象。對我來說似乎很基本。 – GGrec

+0

'String str'是一個String引用**。 –

回答

2

您沒有分配給相同的str對象。

查看replaceAll等方法,您將看到它們返回String,即replaceAll方法創建的新String對象。

所以str=str.replaceAll()需要參考str,請撥打replaceAll()在那StringreplaceAll進程this,然後返回一個新的String對象與該處理的結果。然後您將其分配回原始參考。

2

您需要了解參考文獻:str是對您記憶中某個區域的引用。發生的事情是,Java運行時創建一個新的內存區域,其中所有字符都被刪除,然後將「str」指向新的內存區域。

這與修改已經指向str的內存區域不同。

「不變性」表示變量指向的內存區域不能被修改。內容是固定的。要「修改」它,內存必須被複制,修改,然後重新分配。

「可變」對象可以修改內存中的數據,而無需將舊數據複製到新的內存區域。


順便說一下,在我們的例子中,字符串甚至被複制兩次!

第一次,這種copyies字符串:

replaceAll("[^a-zA-Z0-9\\s]", "") 

然後另一份由

toLowerCase() 

,然後最終分配給您的變量創建。

你的代碼是這樣等於如下:

void test(String str) 
{ 
    String str1 = str.replaceAll("[^a-zA-Z0-9\\s]", ""); 
    String str2 = str1.toLowerCase(); 
    str = str2; 

    System.out.println("\n" +str); 
} 
0

你要明白,在Java中,變量是不是對象;變量是引用到對象。

因此,str不是String對象,它是對對象的引用。 「不可變」表示變量所引用的對象的內容不能改變;這並不意味着變量本身不能被改變來引用不同的對象。

您正在使str指向一個不同的String對象;即,str.replaceAll返回的新String對象。

相關問題