青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

Merlin

Life was like a box of chocolates. You never know what you're gonna get.

   :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
  34 隨筆 :: 0 文章 :: 40 評論 :: 0 Trackbacks
近期到CSDN論壇看看一些網(wǎng)友貼的面試題,其中關(guān)于String的問題常常被提及。我一直以為自己很清楚這個東西了,其實深究起來,發(fā)現(xiàn)自己并不那么清楚,會犯一些錯誤;同時也產(chǎn)生了一些聯(lián)想。小結(jié)一下。

1、"abc"與new String("abc");
????經(jīng)常會問到的面試題:String s = new String("abc");創(chuàng)建了幾個String Object?【如這里創(chuàng)建了多少對象? 和一道小小的面試題 】

????這個問題比較簡單,涉及的知識點包括:

引用變量與對象的區(qū)別;
字符串文字"abc"是一個String對象;
文字池[pool of literal strings]和堆[heap]中的字符串對象。
????一、引用變量與對象:除了一些早期的Java書籍和現(xiàn)在的垃圾書籍,人們都可以從中比較清楚地學(xué)習(xí)到兩者的區(qū)別。A aa;語句聲明一個類A的引用變量aa[我常常稱之為句柄],而對象一般通過new創(chuàng)建。所以題目中s僅僅是一個引用變量,它不是對象。[ref 句柄、引用與對象]

????二、Java中所有的字符串文字[字符串常量]都是一個String的對象。有人[特別是C程序員]在一些場合喜歡把字符串"當作/看成"字符數(shù)組,這也沒有辦法,因為字符串與字符數(shù)組存在一些內(nèi)在的聯(lián)系。事實上,它與字符數(shù)組是兩種完全不同的對象。

????????System.out.println("Hello".length());
????????char[] cc={'H','i'};
????????System.out.println(cc.length);

????三、字符串對象的創(chuàng)建:由于字符串對象的大量使用[它是一個對象,一般而言對象總是在heap分配內(nèi)存],Java中為了節(jié)省內(nèi)存空間和運行時間[如比較字符串時,==比equals()快],在編譯階段就把所有的字符串文字放到一個文字池[pool of literal strings]中,而運行時文字池成為常量池的一部分。文字池的好處,就是該池中所有相同的字符串常量被合并,只占用一個空間。我們知道,對兩個引用變量,使用==判斷它們的值[引用]是否相等,即指向同一個對象:

				String s1 = "abc" ;
String s2 = "abc" ;
if( s1 == s2 )
????System.out.println("s1,s2 refer to the same object");
else???? System.out.println("trouble");


????這里的輸出顯示,兩個字符串文字保存為一個對象。就是說,上面的代碼只在pool中創(chuàng)建了一個String對象。

????現(xiàn)在看String s = new String("abc");語句,這里"abc"本身就是pool中的一個對象,而在運行時執(zhí)行new String()時,將pool中的對象復(fù)制一份放到heap中,并且把heap中的這個對象的引用交給s持有。ok,這條語句就創(chuàng)建了2個String對象。

				String s1 = new String("abc") ;
String s2 = new String("abc") ;
if( s1 == s2 ){ //不會執(zhí)行的語句}


????這時用==判斷就可知,雖然兩個對象的"內(nèi)容"相同[equals()判斷],但兩個引用變量所持有的引用不同,

????BTW:上面的代碼創(chuàng)建了幾個String Object? [三個,pool中一個,heap中2個。]
????[Java2 認證考試學(xué)習(xí)指南 (第4版)( 英文版)p197-199有圖解。]


2、字符串的+運算和字符串轉(zhuǎn)換
????字符串轉(zhuǎn)換和串接是很基礎(chǔ)的內(nèi)容,因此我以為這個問題簡直就是送分題。事實上,我自己就答錯了。

String str = new String("jf"); // jf是接分
str = 1+2+str+3+4;
一共創(chuàng)建了多少String的對象?[我開始的答案:5個。jf、new、3jf、3jf3、3jf34]

????首先看JLS的有關(guān)論述:

????一、字符串轉(zhuǎn)換的環(huán)境[JLS 5.4 String Conversion]

????字符串轉(zhuǎn)換環(huán)境僅僅指使用雙元的+運算符的情況,其中一個操作數(shù)是一個String對象。在這一特定情形下,另一操作數(shù)轉(zhuǎn)換成String,表達式的結(jié)果是這兩個String的串接。

????二、串接運算符[JLS 15.18.1 String Concatenation Operator + ]

????如果一個操作數(shù)/表達式是String類型,則另一個操作數(shù)在運行時轉(zhuǎn)換成一個String對象,并兩者串接。此時,任何類型都可以轉(zhuǎn)換成String。[這里,我漏掉了"3"和"4"]

如果是基本數(shù)據(jù)類型,則如同首先轉(zhuǎn)換成其包裝類對象,如int x視為轉(zhuǎn)換成Integer(x)。
現(xiàn)在就全部統(tǒng)一到引用類型向String的轉(zhuǎn)換了。這種轉(zhuǎn)換如同[as if]調(diào)用該對象的無參數(shù)toString方法。[如果是null則轉(zhuǎn)換成"null"]。因為toString方法在Object中定義,故所有的類都有該方法,而且Boolean, Character, Integer, Long, Float, Double, and String改寫了該方法。
關(guān)于+是串接還是加法,由操作數(shù)決定。1+2+str+3+4 就很容易知道是"3jf34"。[BTW :在JLS的15.18.1.3中舉的一個jocular little example,真的很無趣。]
????下面的例子測試了改寫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)化

按照上述說法,str = 1+2+str+3+4;語句似乎應(yīng)該就應(yīng)該生成5個String對象:

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é)果仍然是猜測。

????為了減少創(chuàng)建中間過渡性的字符串對象,提高反復(fù)進行串接運算時的性能,a Java compiler可以使用StringBuffer或者類似的技術(shù),或者把轉(zhuǎn)換與串接合并成一步。例如:對于 a + b + c ,Java編譯器就可以將它視為[as if]

????new StringBuffer().append(a).append(b).append(c).toString();

????注意,對于基本類型和引用類型,在append(a)過程中仍然要先將參數(shù)轉(zhuǎn)換,從這個觀點看,str = 1+2+str+3+4;創(chuàng)建的字符串可能是"3"、"4"和"3jf34"[以及一個StringBuffer對象]。

????現(xiàn)在我仍然不知道怎么回答str = 1+2+str+3+4;創(chuàng)建了多少String的對象,。或許,這個問題不需要過于研究,至少SCJP不會考它。

3、這又不同:str = "3"+"jf"+"3"+"4";
????如果是一個完全由字符串文字組成的表達式,則在編譯時,已經(jīng)被優(yōu)化而不會在運行時創(chuàng)建中間字符串。測試代碼如下:

				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)");


????可見,str1與str2指向同一個對象,這個對象在pool中。所有遵循Java Language Spec的編譯器都必須在編譯時對constant expressions 進行簡化。JLS規(guī)定:Strings computed by constant expressions (ý15.28) are computed at compile time and then treated as if they were literals.

????對于String str2 ="3"+"jf"+"3"+"4";我們說僅僅創(chuàng)建一個對象。注意,“創(chuàng)建多少對象”的討論是說運行時創(chuàng)建多少對象。

????BTW:編譯時優(yōu)化

				????String x = "aaa " + "bbb ";
????if (false) {
????????x = x + "ccc ";
????}
????x +=??"ddd ";

????等價于:

????String x = "aaa bbb ";
????x = x + "ddd ";
//這個地方我自己進行了編譯,不過和他的結(jié)論不一樣,好像當用x+="ddd"的時候和直接的x="aaa"+"bbb"+"ddd" 不同,但是具體為什么我也不清楚,正在研究中。。。

4、不變類
????String對象是不可改變的(immutable)。有人對str = 1+2+str+3+4;語句提出疑問,怎么str的內(nèi)容可以改變?其實仍然是因為不清楚:引用變量與對象的區(qū)別。str僅僅是引用變量,它的值——它持有的引用可以改變。你不停地創(chuàng)建新對象,我就不斷地改變指向。[參考TIJ的Read-only classes。]

????不變類的關(guān)鍵是,對于對象的所有操作都不可能改變原來的對象[只要需要,就返回一個改變了的新對象]。這就保證了對象不可改變。為什么要將一個類設(shè)計成不變類?有一個OOD設(shè)計的原則:Law of Demeter。其廣義解讀是:

????使用不變類。只要有可能,類應(yīng)當設(shè)計為不變類。
posted on 2006-07-11 22:29 Merlin 閱讀(415) 評論(0)  編輯 收藏 引用 所屬分類: java基礎(chǔ)篇
青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲精品一区二区三| 欧美日韩国产综合网| 欧美在线免费| 欧美亚州韩日在线看免费版国语版| 亚洲日本久久| 一区在线观看| 看欧美日韩国产| 欧美成人首页| 亚洲精品欧美| 国产精品xxxxx| 欧美亚洲在线| 蜜臀久久99精品久久久久久9| 亚洲人成77777在线观看网| 欧美精品v日韩精品v韩国精品v | 亚洲国产精品ⅴa在线观看 | 一区二区三区国产在线观看| 欧美视频在线播放| 先锋影音国产一区| 99视频精品在线| 国产精品国码视频| 久久久久久电影| 亚洲三级视频| 久久精品国产清高在天天线| 一区视频在线看| 欧美日韩一卡二卡| 久久疯狂做爰流白浆xx| 欧美成人一区二区三区| 亚洲欧美乱综合| 狠狠色噜噜狠狠色综合久| 毛片基地黄久久久久久天堂| avtt综合网| 久久香蕉国产线看观看av| 99视频精品免费观看| 国内伊人久久久久久网站视频| 欧美刺激午夜性久久久久久久| 亚洲欧美激情一区二区| 亚洲国产精品久久| 久久久久一区二区| 亚洲一区精彩视频| 亚洲欧洲一区二区三区久久| 国产精品一区二区久激情瑜伽| 免费在线观看精品| 欧美在线视频一区二区三区| 洋洋av久久久久久久一区| 久久亚洲影音av资源网| 午夜国产精品影院在线观看 | 亚洲综合精品一区二区| 亚洲国产一区二区三区高清| 国产精品一区免费观看| 欧美精品一区二区在线播放| 久久网站热最新地址| 亚洲一区二区免费视频| 亚洲乱码久久| 欧美激情在线狂野欧美精品| 久久激情视频| 亚洲专区免费| 夜夜嗨av一区二区三区四季av| 亚洲第一综合天堂另类专| 国产精品视频免费观看| 欧美日韩精选| 欧美xart系列在线观看| 久久亚洲私人国产精品va媚药| 欧美一级久久久| 国产精品一区二区在线观看不卡| 亚洲第一级黄色片| 久久久亚洲国产美女国产盗摄| 亚洲一区二区三区涩| 夜夜精品视频| 这里只有精品在线播放| 夜夜嗨av色综合久久久综合网| 亚洲人成亚洲人成在线观看图片| 亚洲电影在线免费观看| 国产精品免费久久久久久| 欧美日韩国产成人在线| 欧美精品久久99| 欧美成人午夜视频| 欧美精品午夜| 欧美日韩精品免费观看视频完整 | 在线一区二区三区做爰视频网站 | 午夜综合激情| 性欧美暴力猛交另类hd| 亚洲欧美亚洲| 亚洲欧美日韩一区| 小处雏高清一区二区三区| 亚洲欧美综合一区| 久久久99精品免费观看不卡| 亚洲一区二区免费视频| 亚洲中无吗在线| 欧美亚洲在线| 久久久欧美精品| 免费中文日韩| 亚洲黑丝一区二区| 一区二区三区欧美在线| 亚洲午夜高清视频| 亚洲视频免费看| 欧美一级成年大片在线观看| 久久av资源网站| 免费在线看一区| 欧美色综合天天久久综合精品| 欧美日韩一区国产| 国产欧美日韩视频| 在线国产亚洲欧美| 亚洲麻豆一区| 亚洲精品日韩欧美| 亚洲男人的天堂在线aⅴ视频| 欧美专区中文字幕| 欧美国产一区二区| 欧美日韩一卡二卡| 亚洲欧美日韩在线| 久久综合国产精品| 欧美午夜精品久久久久免费视| 国产精品亚洲人在线观看| 狠狠久久综合婷婷不卡| 99国产精品久久久久久久久久| 亚洲专区一区| 欧美阿v一级看视频| 一二三区精品| 久久国产精品第一页| 欧美激情免费观看| 国产日韩欧美a| 亚洲理伦电影| 久久精品主播| 99精品欧美一区| 午夜亚洲福利在线老司机| 欧美freesex8一10精品| 欧美午夜宅男影院在线观看| 黑人巨大精品欧美一区二区| 夜夜爽夜夜爽精品视频| 久久综合网色—综合色88| 亚洲美女精品成人在线视频| 亚洲欧美综合网| 欧美日韩精品| 亚洲国产专区校园欧美| 亚洲欧美视频在线观看| 亚洲国产成人在线视频| 久久av二区| 国产精品xxxxx| 99精品欧美一区| 另类图片综合电影| 亚洲一区欧美一区| 欧美激情影音先锋| 亚洲国产精品第一区二区| 亚洲一区二区在线免费观看| 久久露脸国产精品| 亚洲欧美日韩电影| 欧美日韩国产精品专区| 亚洲黄网站黄| 久久久久久网址| 亚洲视频综合在线| 欧美网站在线观看| 9i看片成人免费高清| 狂野欧美一区| 欧美在线视频一区二区三区| 国产九九精品| 亚洲欧美视频在线观看| 在线亚洲伦理| 欧美三级乱人伦电影| 99国产精品视频免费观看| 美女主播视频一区| 久久久www免费人成黑人精品| 国产精品v一区二区三区 | 久久精品国产99国产精品澳门| 99视频日韩| 欧美日韩亚洲另类| 亚洲私人影院在线观看| 日韩午夜精品| 欧美日韩亚洲国产精品| 亚洲一区二区三区免费观看 | 中文网丁香综合网| 一本色道久久综合狠狠躁的推荐| 欧美精品啪啪| 中文国产成人精品久久一| 亚洲精品一区在线观看香蕉| 欧美黑人一区二区三区| 日韩系列在线| av成人毛片| 国产精品―色哟哟| 久久久久久电影| 欧美怡红院视频一区二区三区| 国产精品综合久久久| 久久免费精品视频| 欧美aⅴ99久久黑人专区| 亚洲精品美女在线观看| 亚洲精品看片| 国产精品乱人伦中文| 久久国产毛片| 午夜亚洲一区| 亚洲成色www久久网站| 免费在线看成人av| 欧美伦理91i| 欧美一区二区三区视频在线| 午夜一区二区三视频在线观看| 国产永久精品大片wwwapp| 老司机成人网| 久久久精品免费视频| 亚洲精品一二| 亚洲制服少妇| 亚洲二区视频| 一区二区三区欧美视频| 影音先锋中文字幕一区|