java進(jìn)階之字符串替換的思考 -轉載2007年03月26日 星期一 上午 10:51最近
在開(kāi)發(fā)的過(guò)程中用到了字符串的替換, 本來(lái)覺(jué)得挺簡(jiǎn)單的問(wèn)題,卻總也解決不了。字符串明明是替換了,卻總也輸出不了正確結果,很是郁悶,到底是為什么呢?
先來(lái)看我的代碼:
Newsdetials nt=(Newsdetials)ntIter.next();
System.out.println("新聞明細記錄 "+nt);
String content=nt.getContent();
System.out.println("新聞的內容是 : "+content);
//轉換字符串中的雙引號為單引號
content.replaceAll("\"","'");
System.out.println("替換后的字符傳是: "+content);
程序解釋?zhuān)?br> 程序的前部分是通過(guò)迭代器來(lái)遍歷新聞的明細記錄。
我的目的是想用雙引號來(lái)替換掉字符串中的單引號。
以上是我開(kāi)始使用的方法,我輸出的結果是什么呢?也許你會(huì )和我當初的想法相同?輸出的是替換后的內容。
答案是錯的。輸出的內容和其替換前的內容相同。明明替換了,這是為什么呢?我也是好久都沒(méi)找到答案。
一個(gè)偶然的機會(huì ),讓我實(shí)現了我的目的。我的實(shí)現如下:
Newsdetials nt=(Newsdetials)ntIter.next();
System.out.println("新聞明細記錄 "+nt);
String content=nt.getContent();
System.out.println("新聞的內容是 : "+content);
//轉換字符串中的雙引號為單引號
String content0=content.replaceAll("\"","'");
System.out.println("替換后的字符傳是: "+content0);
程序解釋?zhuān)?br>這一段代碼看上去和前段相同,但卻實(shí)現了我的目的。
我很是不解,就看了一下源代碼,才發(fā)現其中的奧妙。我們分析一下上面的兩段程序:
唯一的不同點(diǎn)是:后者將替換后的字符串賦給了另一個(gè)字符串變量,也就是說(shuō)將替換后的字符串取出,而前者沒(méi)有。也就是這一點(diǎn)導致了結果的不同。
于是我就查看了其實(shí)現的源代碼:
我們來(lái)看String的replaceAll()方法的實(shí)現:
public String replaceAll(String regex, String replacement) {
return Pattern.compile(regex).matcher(this).replaceAll(replacement);
}
我們可以看到,其最終是調用了matcher(this).replaceAll(replacement)方法來(lái)實(shí)現的,我們看其是怎么實(shí)現的:
public String replaceAll(String replacement) {
reset();
boolean result = find();
if (result) {
StringBuffer sb = new StringBuffer();
do {
appendReplacement(sb, replacement);
result = find();
} while (result);
appendTail(sb);
return sb.toString();
}
return text.toString();
}
看這一段代碼讓我們明白了一切(我只看懂了,確實(shí)有一個(gè)新的對象生成,并且返回了):
我們知道在java中,如果傳遞的是對象,那么是址傳遞,所以讓我們以為,讓原字符串替代后就可以了。同時(shí)我們調用了該字符串的替代方法,直接就修改了其串的值。
上面的代碼告訴我們,錯了。
因為粗體的部分產(chǎn)生了一個(gè)新的對象:StringBuffer的一個(gè)實(shí)例,而返回的是他的串值,而不是原來(lái)的content。
注:查看JDK文檔,replaceAll方法返回的是一個(gè)字符串。這里就得注意了,如果返回的是void,那么就是在原來(lái)的基礎上更改,但返回的是字符串,就有可能是新生成了一個(gè)字符串對象。對于其他方法也一樣。以后如果碰到類(lèi)似問(wèn)題:本來(lái)以為結果應該是這樣,但輸出確實(shí)那樣,這時(shí)建議看看文檔,檢查一下方法的具體用法。
最后還要補充一點(diǎn):String類(lèi)的對象是不可更改的,叫做常量對象。所以replaceAll必定返回一個(gè)新的對象。以后再碰見(jiàn)字符串,并想要改變它的值,那么必定是產(chǎn)生了一個(gè)新的對象
聯(lián)系客服