<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    對(duì)String的深刻理解

    Posted on 2006-08-18 15:41 my 閱讀(214) 評(píng)論(0)  編輯  收藏 所屬分類(lèi): java
    1、"abc"與new String("abc"); 經(jīng)常會(huì)問(wèn)到的面試題:String s = new String("abc");創(chuàng)建了幾個(gè)String Object?【如這里創(chuàng)建了多少對(duì)象? 和一道小小的面試題 】 這個(gè)問(wèn)題比較簡(jiǎn)單,涉及的知識(shí)點(diǎn)包括: 引用變量與對(duì)象的區(qū)別; 字符串文字"abc"是一個(gè)String對(duì)象; 文字池[pool of literal strings]和堆[heap]中的字符串對(duì)象。 一、引用變量與對(duì)象:除了一些早期的Java書(shū)籍和現(xiàn)在的垃圾書(shū)籍,人們都可以從中比較清楚地學(xué)習(xí)到兩者的區(qū)別。A aa;語(yǔ)句聲明一個(gè)類(lèi)A的引用變量aa[我常常稱(chēng)之為句柄],而對(duì)象一般通過(guò)new創(chuàng)建。所以題目中s僅僅是一個(gè)引用變量,它不是對(duì)象。[ref 句柄、引用與對(duì)象] 二、Java中所有的字符串文字[字符串常量]都是一個(gè)String的對(duì)象。有人[特別是C程序員]在一些場(chǎng)合喜歡把字符串"當(dāng)作/看成"字符數(shù)組,這也沒(méi)有辦法,因?yàn)樽址c字符數(shù)組存在一些內(nèi)在的聯(lián)系。事實(shí)上,它與字符數(shù)組是兩種完全不同的對(duì)象。 System.out.println("Hello".length()); char[] cc={'H','i'}; System.out.println(cc.length); 三、字符串對(duì)象的創(chuàng)建:由于字符串對(duì)象的大量使用[它是一個(gè)對(duì)象,一般而言對(duì)象總是在heap分配內(nèi)存],Java中為了節(jié)省內(nèi)存空間和運(yùn)行時(shí)間[如比較字符串時(shí),==比equals()快],在編譯階段就把所有的字符串文字放到一個(gè)文字池[pool of literal strings]中,而運(yùn)行時(shí)文字池成為常量池的一部分。文字池的好處,就是該池中所有相同的字符串常量被合并,只占用一個(gè)空間。我們知道,對(duì)兩個(gè)引用變量,使用==判斷它們的值[引用]是否相等,即指向同一個(gè)對(duì)象: String s1 = "abc" ;String s2 = "abc" ;if( s1 == s2 ) System.out.println("s1,s2 refer to the same object");else System.out.println("trouble"); 這里的輸出顯示,兩個(gè)字符串文字保存為一個(gè)對(duì)象。就是說(shuō),上面的代碼只在pool中創(chuàng)建了一個(gè)String對(duì)象。 現(xiàn)在看String s = new String("abc");語(yǔ)句,這里"abc"本身就是pool中的一個(gè)對(duì)象,而在運(yùn)行時(shí)執(zhí)行new String()時(shí),將pool中的對(duì)象復(fù)制一份放到heap中,并且把heap中的這個(gè)對(duì)象的引用交給s持有。ok,這條語(yǔ)句就創(chuàng)建了2個(gè)String對(duì)象。 String s1 = new String("abc") ;String s2 = new String("abc") ;if( s1 == s2 ){ //不會(huì)執(zhí)行的語(yǔ)句} 這時(shí)用==判斷就可知,雖然兩個(gè)對(duì)象的"內(nèi)容"相同[equals()判斷],但兩個(gè)引用變量所持有的引用不同, BTW:上面的代碼創(chuàng)建了幾個(gè)String Object? [三個(gè),pool中一個(gè),heap中2個(gè)。] [Java2 認(rèn)證考試學(xué)習(xí)指南 (第4版)( 英文版)p197-199有圖解。] 2、字符串的+運(yùn)算和字符串轉(zhuǎn)換 字符串轉(zhuǎn)換和串接是很基礎(chǔ)的內(nèi)容,因此我以為這個(gè)問(wèn)題簡(jiǎn)直就是送分題。事實(shí)上,我自己就答錯(cuò)了。 String str = new String("jf"); // jf是接分 str = 1+2+str+3+4; 一共創(chuàng)建了多少String的對(duì)象?[我開(kāi)始的答案:5個(gè)。jf、new、3jf、3jf3、3jf34] 首先看JLS的有關(guān)論述: 一、字符串轉(zhuǎn)換的環(huán)境[JLS 5.4 String Conversion] 字符串轉(zhuǎn)換環(huán)境僅僅指使用雙元的+運(yùn)算符的情況,其中一個(gè)操作數(shù)是一個(gè)String對(duì)象。在這一特定情形下,另一操作數(shù)轉(zhuǎn)換成String,表達(dá)式的結(jié)果是這兩個(gè)String的串接。 二、串接運(yùn)算符[JLS 15.18.1 String Concatenation Operator + ] 如果一個(gè)操作數(shù)/表達(dá)式是String類(lèi)型,則另一個(gè)操作數(shù)在運(yùn)行時(shí)轉(zhuǎn)換成一個(gè)String對(duì)象,并兩者串接。此時(shí),任何類(lèi)型都可以轉(zhuǎn)換成String。[這里,我漏掉了"3"和"4"] 如果是基本數(shù)據(jù)類(lèi)型,則如同首先轉(zhuǎn)換成其包裝類(lèi)對(duì)象,如int x視為轉(zhuǎn)換成Integer(x)。 現(xiàn)在就全部統(tǒng)一到引用類(lèi)型向String的轉(zhuǎn)換了。這種轉(zhuǎn)換如同[as if]調(diào)用該對(duì)象的無(wú)參數(shù)toString方法。[如果是null則轉(zhuǎn)換成"null"]。因?yàn)閠oString方法在Object中定義,故所有的類(lèi)都有該方法,而且Boolean, Character, Integer, Long, Float, Double, and String改寫(xiě)了該方法。 關(guān)于+是串接還是加法,由操作數(shù)決定。1+2+str+3+4 就很容易知道是"3jf34"。[BTW :在JLS的15.18.1.3中舉的一個(gè)jocular little example,真的很無(wú)趣。] 下面的例子測(cè)試了改寫(xiě)toString方法的情況.。 class A{ int i = 10; public static void main(String []args){ String str = new String("jf"); str += new A(); System.out.print(str); } public String toString(){ return " a.i ="+i+"\n"; }} 三、字符串轉(zhuǎn)換的優(yōu)化 按照上述說(shuō)法,str = 1+2+str+3+4;語(yǔ)句似乎應(yīng)該就應(yīng)該生成5個(gè)String對(duì)象: 1+2 =3,then 3→Integer(3)→"3" in pool? [假設(shè)如此] "3"+str(in heap) = "3jf" (in heap) "3jf" +3 ,first 3→Integer(3)→"3" in pool? [則不創(chuàng)建] then "3jf3" "3jf3"+4 create "4" in pool then "3jf34" 這里我并不清楚3、4轉(zhuǎn)換成字符串后是否在池中,所以上述結(jié)果仍然是猜測(cè)。 為了減少創(chuàng)建中間過(guò)渡性的字符串對(duì)象,提高反復(fù)進(jìn)行串接運(yùn)算時(shí)的性能,a Java compiler可以使用StringBuffer或者類(lèi)似的技術(shù),或者把轉(zhuǎn)換與串接合并成一步。例如:對(duì)于 a + b + c ,Java編譯器就可以將它視為[as if] new StringBuffer().append(a).append(b).append(c).toString(); 注意,對(duì)于基本類(lèi)型和引用類(lèi)型,在append(a)過(guò)程中仍然要先將參數(shù)轉(zhuǎn)換,從這個(gè)觀點(diǎn)看,str = 1+2+str+3+4;創(chuàng)建的字符串可能是"3"、"4"和"3jf34"[以及一個(gè)StringBuffer對(duì)象]。 現(xiàn)在我仍然不知道怎么回答str = 1+2+str+3+4;創(chuàng)建了多少String的對(duì)象,?;蛟S,這個(gè)問(wèn)題不需要過(guò)于研究,至少SCJP不會(huì)考它。 3、這又不同:str = "3"+"jf"+"3"+"4"; 如果是一個(gè)完全由字符串文字組成的表達(dá)式,則在編譯時(shí),已經(jīng)被優(yōu)化而不會(huì)在運(yùn)行時(shí)創(chuàng)建中間字符串。測(cè)試代碼如下: String str1 ="3jf34"; String str2 ="3"+"jf"+"3"+"4"; if(str1 == str2) { System.out.println("str1 == str2"); }else { System.out.println("think again"); } if(str2.equals(str1)) System.out.println("yet str2.equals(str1)"); 可見(jiàn),str1與str2指向同一個(gè)對(duì)象,這個(gè)對(duì)象在pool中。所有遵循Java Language Spec的編譯器都必須在編譯時(shí)對(duì)constant expressions 進(jìn)行簡(jiǎn)化。JLS規(guī)定:Strings computed by constant expressions (y15.28) are computed at compile time and then treated as if they were literals. 對(duì)于String str2 ="3"+"jf"+"3"+"4";我們說(shuō)僅僅創(chuàng)建一個(gè)對(duì)象。注意,“創(chuàng)建多少對(duì)象”的討論是說(shuō)運(yùn)行時(shí)創(chuàng)建多少對(duì)象。 BTW:編譯時(shí)優(yōu)化 String x = "aaa " + "bbb "; if (false) { x = x + "ccc "; } x += "ddd "; 等價(jià)于: String x = "aaa bbb "; x = x + "ddd "; 4、不變類(lèi) String對(duì)象是不可改變的(immutable)。有人對(duì)str = 1+2+str+3+4;語(yǔ)句提出疑問(wèn),怎么str的內(nèi)容可以改變?其實(shí)仍然是因?yàn)椴磺宄阂米兞颗c對(duì)象的區(qū)別。str僅僅是引用變量,它的值——它持有的引用可以改變。你不停地創(chuàng)建新對(duì)象,我就不斷地改變指向。[參考TIJ的Read-only classes。] 不變類(lèi)的關(guān)鍵是,對(duì)于對(duì)象的所有操作都不可能改變?cè)瓉?lái)的對(duì)象[只要需要,就返回一個(gè)改變了的新對(duì)象]。這就保證了對(duì)象不可改變。為什么要將一個(gè)類(lèi)設(shè)計(jì)成不變類(lèi)?有一個(gè)OOD設(shè)計(jì)的原則:Law of Demeter。其廣義解讀是: 使用不變類(lèi)。只要有可能,類(lèi)應(yīng)當(dāng)設(shè)計(jì)為不變類(lèi)。

    posts - 63, comments - 45, trackbacks - 0, articles - 99

    Copyright © my

    主站蜘蛛池模板: 免费大黄网站在线观看| 97亚洲熟妇自偷自拍另类图片| 黄 色一级 成 人网站免费| 久久久久久亚洲精品| 最近中文字幕mv免费高清视频7 | 男的把j放进女人下面视频免费| 久久久久久亚洲AV无码专区| 免费无码又爽又刺激高潮的视频 | 日本xxxx色视频在线观看免费| 亚洲人成毛片线播放| 免费a级黄色毛片| 最近2019免费中文字幕视频三 | 无码免费一区二区三区免费播放| 日韩亚洲国产高清免费视频| 亚洲日韩小电影在线观看| 曰批全过程免费视频在线观看| 成人片黄网站色大片免费观看cn| ass亚洲**毛茸茸pics| 亚洲老妈激情一区二区三区| 成人人观看的免费毛片| 中文字幕免费不卡二区| 国产精品亚洲综合网站| 久久亚洲熟女cc98cm| 久久久久国产亚洲AV麻豆| 一区二区无码免费视频网站| 暖暖免费在线中文日本| 欧洲美女大片免费播放器视频| 亚洲AV无码精品蜜桃| 久久精品视频亚洲| 超清首页国产亚洲丝袜| 国产午夜无码视频免费网站| 日本成年免费网站| 99国产精品免费视频观看| 精品国产污污免费网站入口在线| 国产精品亚洲va在线观看| 亚洲天堂2017无码中文| 亚洲精品在线免费观看视频| 亚洲AV无码精品无码麻豆| 国产亚洲精品高清在线| 亚洲AV日韩精品一区二区三区| 免费被黄网站在观看|