2013-12-16 26 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对象。

相关问题