版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
通用程序設(shè)計(jì)
將局部變量的作用域最小化最小化局部變量的方法:最有效的方法是在它第一次使用時(shí)聲明。幾乎每個(gè)局部變量聲明都應(yīng)該包含一個(gè)初始值,否那么編譯也通不過(guò)。方法小而集中,每個(gè)方法僅僅處理一種活動(dòng)。如果把兩個(gè)操作合并到同一個(gè)方法中,與其中一個(gè)操作相關(guān)的局部變量就有可能會(huì)出現(xiàn)在執(zhí)行另一個(gè)操作的代碼范圍之內(nèi)。為了防止這種情況發(fā)生,只要把這個(gè)方法分成兩個(gè),每個(gè)方法各執(zhí)行一個(gè)操作。for-each循環(huán)優(yōu)先于傳統(tǒng)的for循環(huán)集合上迭代優(yōu)先考慮:for(Iteratori=c.iterator();i.hasNext();){ doSomething((Element)i.next());}數(shù)組上迭代優(yōu)先考慮:for(inti=0;i<a.length;i++){ doSomething(a[i]);}這些習(xí)慣用法要好于while循環(huán)但也不完美。迭代器與索引都有些混亂。而且,它們還可能引起錯(cuò)誤。在上面的循環(huán)中迭代器與索引都出現(xiàn)了三次,其中有兩個(gè)地方可能帶來(lái)錯(cuò)誤,如果確實(shí)出現(xiàn)了這種錯(cuò)誤,卻無(wú)法保證編譯器能捕獲到這些錯(cuò)誤。
版本1.5引入的for-each循環(huán)從混亂中解脫出來(lái)了,而且完全擺脫了隱藏在迭代器與索引變量后的可能的出錯(cuò)的時(shí)機(jī)。這種慣用法對(duì)集合與數(shù)組都適用:for(Elemente:elements){ doSomething(e);}for-each循環(huán)優(yōu)先于傳統(tǒng)的for循環(huán)〔續(xù)〕與傳統(tǒng)的for循環(huán)相比,在簡(jiǎn)潔及預(yù)防bug方面,for-each循環(huán)有巨大的優(yōu)勢(shì),而且沒(méi)有性能損耗。應(yīng)該盡可能地使用for-each。但是有三種普遍情況無(wú)法使用for-each循環(huán):1、過(guò)濾——如果需要在集合上遍歷且刪除選定的元素,就要使用顯式的迭代,并調(diào)用它的remove方法。2、轉(zhuǎn)換——如果需要在list或數(shù)組上遍歷且要替換局部或所有的元素值,那么需要list的迭代器或數(shù)組的索引去設(shè)置這些值。3、平行迭代——如果需要并行的遍歷多個(gè)集合,那么需要顯式的控制迭代器或索引變量,以便所有的迭代器或索引能協(xié)同推進(jìn)。了解和使用類庫(kù)不要重新創(chuàng)造輪子,如果你要做的事情是很常見(jiàn)的,就去查下有沒(méi)有這樣的實(shí)現(xiàn)類,如果有,那么使用它,這樣會(huì)降低你實(shí)現(xiàn)相應(yīng)功能的投入和代碼的出錯(cuò)率。使用標(biāo)準(zhǔn)庫(kù)的好處:通過(guò)使用標(biāo)準(zhǔn)庫(kù),你可以充分利用這些編寫標(biāo)準(zhǔn)庫(kù)的專家知識(shí),以及在你之前其他人的使用經(jīng)驗(yàn)。不必浪費(fèi)時(shí)間為那些與工作不太相關(guān)的問(wèn)題提供特別的解決方案。它們的性能往往會(huì)隨著時(shí)間的推移而不斷提高,無(wú)需你做任何努力??梢允棺约旱拇a融入主流,這樣的代碼更易讀、更易維護(hù)、更易被大多數(shù)的開(kāi)發(fā)人員重用。比較常見(jiàn)的一些標(biāo)準(zhǔn)類庫(kù)java.lang、java.util、java.io如果要求精確的答案,請(qǐng)防止使用float和doublefloat和double主要是為了在科學(xué)計(jì)算和工程計(jì)算提供較為精確,快速的近似計(jì)算設(shè)計(jì)的。沒(méi)有提供完全精確的結(jié)果,所以不應(yīng)該用在要求精確結(jié)果的場(chǎng)合。特別是不適合表示貨幣,在平時(shí)的使用中應(yīng)該防止。例: System.out.println("result1="+(1.03-0.42)); System.out.println("result2="+(1.00-9*.10));輸出結(jié)果: result2=0.09999999999999998如果希望系統(tǒng)來(lái)處理十進(jìn)制的小數(shù)點(diǎn),可以使用BigDecimal,如果不考慮小數(shù)的處理,數(shù)值范圍沒(méi)有超過(guò)9位的那么可以用int來(lái)處理,如果不超過(guò)18位的,那么可以用long來(lái)處理,超過(guò)18位那么使用BigDecimal來(lái)處理。了解字符串連接的性能字符串連接操作符(+)把多個(gè)字符串合并為一個(gè)字符串。為連接N個(gè)字符串而重復(fù)地使用“+”連接,要消耗N的平方級(jí)別的時(shí)間。這是由于字符串不可變導(dǎo)致的結(jié)果。當(dāng)兩個(gè)字符串被連接的時(shí)候,它們的內(nèi)容都要被拷貝。例:如果數(shù)目巨大,這個(gè)方法的執(zhí)行時(shí)間難以估算。為了提高性能,故改寫如下:假設(shè)以上兩種做法,是進(jìn)行100次的拼接,第二種比第一種要快幾十倍所以,除非性能無(wú)關(guān)緊要,請(qǐng)用StringBuffer代替String。謹(jǐn)慎地使用本地方法從歷史上看,本地方法主要有三種用途:提供“訪問(wèn)與平臺(tái)相關(guān)的設(shè)施”的能力提供訪問(wèn)老式代碼庫(kù)的能力實(shí)現(xiàn)性能關(guān)鍵的局部,提高系統(tǒng)性能。本地方法是有容易產(chǎn)生平安隱患,而且也是不可移植的。同時(shí),在進(jìn)入和退出本地代碼的時(shí)候,要需要較高的固定開(kāi)銷,如果本地代碼制作少量工作的話,還可能會(huì)降低性能。所以,盡量使用Java自身提供的方法來(lái)代替本地方法〔如用Java提供的新功能來(lái)代替以前只有C語(yǔ)言能實(shí)現(xiàn)的功能〕,這樣可以使系統(tǒng)變得更加平安,系統(tǒng)可移植性更高,也使代碼變得更加容易閱讀,如果一定要使用本地方法,請(qǐng)加強(qiáng)測(cè)試,并盡可能的少用。謹(jǐn)慎地進(jìn)行優(yōu)化與優(yōu)化相關(guān)的格言:很多計(jì)算上的過(guò)失都被歸咎于效率原因,不是其他的原因——甚至包括盲目的做傻事。 ——WilliamA.Wulf(美國(guó)工程院院長(zhǎng)、弗吉尼亞大學(xué)計(jì)算機(jī)科學(xué)AT&T教授)不要去計(jì)較一些小的效率上的得失,在97%的情況下,不成熟的優(yōu)化才是一切問(wèn)題的根源。 ——DonaldE.Knuth(經(jīng)典巨著《計(jì)算機(jī)程序設(shè)計(jì)的藝術(shù)》的作者)做優(yōu)化時(shí),要遵守兩條原那么:不要做優(yōu)化(僅對(duì)專家)還是不要做優(yōu)化——也就是說(shuō):在你還沒(méi)有絕對(duì)清晰的優(yōu)化方案之前,請(qǐng)不要優(yōu)化(面向數(shù)據(jù)結(jié)構(gòu)的軟件設(shè)計(jì)方法的創(chuàng)造者)上面三個(gè)格言比Java的出現(xiàn)早了20年。 但是講述了一個(gè)深刻的道理:優(yōu)化更容易帶來(lái)傷害,而不是好處,特別是不成熟的優(yōu)化。努力寫好的程序而不是快的程序。應(yīng)該在設(shè)計(jì)階段就考慮好的結(jié)構(gòu),性能的優(yōu)化可以在完成程序之后,當(dāng)然不是指編寫程序額時(shí)候忽略性能問(wèn)題。
如果一個(gè)系統(tǒng)有了清晰、簡(jiǎn)明、結(jié)構(gòu)良好的實(shí)現(xiàn),請(qǐng)謹(jǐn)慎對(duì)其進(jìn)行優(yōu)化,因?yàn)?0%的性能問(wèn)題存在于20%的代碼中,找出影響性能的代碼才是問(wèn)題的關(guān)鍵。異常
只針對(duì)異常的情況下才使用異常異常應(yīng)該只用于異常的情況下;它們永遠(yuǎn)不應(yīng)該用于正常的控制流對(duì)可恢復(fù)的情況使用受檢異常,對(duì)編程錯(cuò)誤使用運(yùn)行時(shí)異常Java提供了三種可拋出結(jié)構(gòu):受檢異常、運(yùn)行時(shí)異常和錯(cuò)誤對(duì)可恢復(fù)的情況使用已檢查異常,對(duì)程序錯(cuò)使用運(yùn)行時(shí)異常。例如:某個(gè)對(duì)象在數(shù)據(jù)庫(kù)中已經(jīng)存在,就屬于可恢復(fù)的異?!荒茉賲⒓幽莻€(gè)對(duì)象了,如果使用關(guān)鍵字約束的話數(shù)據(jù)庫(kù)連接錯(cuò),就屬于不可恢復(fù)的異常,你的程序不可能對(duì)它做任何處只能捕捉它。防止不必要的使用受檢的異常
盡量使用標(biāo)準(zhǔn)的異常專家級(jí)程序與缺乏經(jīng)驗(yàn)程序員一個(gè)最主要的區(qū)分是,專家追求高度的代碼重用,并且通常也能實(shí)現(xiàn)這樣的代碼重用。代碼重用是值的提倡的,這是條通用的規(guī)那么,異常也不例外。重用異常的好處有三:它使你的API更加易于學(xué)習(xí)和使用,因?yàn)樗c程序員原來(lái)已經(jīng)熟悉的習(xí)慣用法是一致的。對(duì)于用到這些API的程序而言,它們的可讀性更好,因?yàn)樗鼈儾粫?huì)充滿著程序員不熟悉的異常。異常類越少,意味著內(nèi)存占用越小,并且裝載這些類的時(shí)間開(kāi)銷越小。Java平臺(tái)庫(kù)中迄今為止最常用的異常如下:IllegalArgumentException 不合法的參數(shù)異常IllegalStateException 在不合理或不正確時(shí)間內(nèi)喚醒一方法時(shí)出現(xiàn)的異常〔如初始化不恰當(dāng)〕NullPointerException 空指針異常IndexOutOfBoundsException 下標(biāo)越界ConcurrentModificationException 在禁止并發(fā)修改的情況下,對(duì)象檢測(cè)到并發(fā)修改UnsupportedOperationException 對(duì)象不支持客戶請(qǐng)求的方法選擇重用哪個(gè)異常并沒(méi)有唯一的答案,根據(jù)具體情況來(lái)選擇。其他的異常也可以使用,只要確保拋出異常的條件與要求一致即可。努力使失敗保持原子性一般而言,一個(gè)失敗的方法調(diào)用應(yīng)該使對(duì)象保持“它在被調(diào)用之前的狀態(tài)”,具有這種屬性的方法被稱為具有失敗原子性。有幾種方法可以獲得這種效果:使用非可變對(duì)象在可變對(duì)象上的操作,應(yīng)在執(zhí)行前檢查參數(shù)的有效性,這樣正式操作之前,如果有錯(cuò)誤,立馬排除異常寫一段恢復(fù)代碼,在執(zhí)行失敗的情況下,回滾到操作開(kāi)始之前的狀態(tài)〔不常用〕在對(duì)象的一份臨時(shí)拷貝上執(zhí)行操作,當(dāng)完成之后,再把臨時(shí)拷貝中的結(jié)果復(fù)制給原來(lái)的對(duì)象,如Collections.sort在執(zhí)行排序之前,先把它的輸入轉(zhuǎn)儲(chǔ)到一個(gè)數(shù)組中,這樣既能降低內(nèi)循環(huán)的開(kāi)銷,又能保證在排序失敗的時(shí)候,輸入列表保持原樣。注意:在有些場(chǎng)合下,如果實(shí)際失敗原子性開(kāi)銷與復(fù)雜性比較大,那么要考慮是否需要實(shí)現(xiàn)。不要忽略異常要忽略一個(gè)異常非常容易,只需要將方法調(diào)用通過(guò)try語(yǔ)句包圍起來(lái),并包含一個(gè)空的catch塊,空catch塊會(huì)使異常達(dá)不到應(yīng)有的目的除非有特殊的需求,否那么不要吃掉異常,至少在catch中包含一條說(shuō)明,用以解釋忽略這個(gè)異常的原因。否那么,就是去了異常本來(lái)的意義。就算是簡(jiǎn)單地將一個(gè)未被檢查的異常傳播到外界也至少會(huì)使程序迅速地失敗,從而保存了有助于調(diào)試該失敗條件信息,比異常被忽略后的一個(gè)不可預(yù)測(cè)的時(shí)刻程序失敗這種情況要強(qiáng)。并發(fā)
同步訪問(wèn)共享的可變數(shù)據(jù)關(guān)鍵字synchronized可以保證在同一時(shí)刻,只有一個(gè)線程可以執(zhí)行某一個(gè)方法,或者某一個(gè)代碼塊一般認(rèn)為同步就是一種互斥的方式,不是很全面。同步的意義:同步不僅可以阻止一個(gè)線程看到對(duì)象處于不一致的狀態(tài)中,它還可以保證通過(guò)一系列看似順序執(zhí)行的狀態(tài)轉(zhuǎn)變序列,對(duì)象從一種一致的狀態(tài)變遷到另外一種一致的狀態(tài)。每一個(gè)線程進(jìn)入到一個(gè)被同步的方法或是代碼塊的時(shí)候,它會(huì)看到由同一個(gè)鎖控制的以前所有狀態(tài)轉(zhuǎn)變的結(jié)果。當(dāng)線程退出了這個(gè)被同步的區(qū)域之后,任何線程在進(jìn)入到由這同一把鎖同步的區(qū)域時(shí),它就可以看到由前面那個(gè)線程帶來(lái)的狀態(tài)轉(zhuǎn)變〔如果有狀態(tài)轉(zhuǎn)變的話〕。也就是代碼是固定的,變量的地址,或是值變量也是固定的,不同的線程會(huì)造成數(shù)據(jù)被修改的情況,第2個(gè)線程進(jìn)入就會(huì)看到被修改的內(nèi)存值域。Java語(yǔ)言保證讀或者寫一個(gè)變量是原子的,除非這個(gè)變量類型為long或是double.也就是說(shuō),讀入一個(gè)非long或double類型的變量,可以保證返回值一定是某個(gè)線程保存在該變量中的,即使多個(gè)線程在沒(méi)有同步的情況下并發(fā)修改這個(gè)變量,也是如此。有些人說(shuō),為了提高性能,在讀或?qū)懺訑?shù)據(jù)的時(shí)候,你應(yīng)該防止使用同步。其實(shí)這個(gè)建議是非常危險(xiǎn)而且是錯(cuò)誤的。雖然原子性保證了一個(gè)線程在讀取原子數(shù)據(jù)的時(shí)候,不會(huì)看到一個(gè)隨機(jī)的數(shù)值,但是它并不保證一個(gè)線程寫入的值對(duì)于另外一個(gè)線程是可見(jiàn)的:為了在線程之間可靠的通信,以及為了互斥訪問(wèn),同步是需要的。同步訪問(wèn)共享的可變數(shù)據(jù)〔續(xù)〕簡(jiǎn)而言之:無(wú)論任何時(shí)候當(dāng)多個(gè)線程共享可變數(shù)據(jù)的時(shí)候,每個(gè)讀或?qū)憯?shù)據(jù)的線程必須執(zhí)行同步。如果沒(méi)有同步,就無(wú)法保證一個(gè)線程所做的修改可以被另一個(gè)線程獲知。而且這樣的錯(cuò)誤,是很難調(diào)試和重現(xiàn)的,因?yàn)榫€程調(diào)試是很麻煩的。他們是高度依賴JVM和操作系統(tǒng)硬件平臺(tái)。防止過(guò)度使用同步同步可以給我們?cè)趯?shí)際開(kāi)發(fā)中帶來(lái)很多的好處,合理的使用同步,將會(huì)更好的處理多線程及并發(fā)時(shí)數(shù)據(jù)的共享和一致性。但是,一句情況的不同,過(guò)度的使用同步可能會(huì)導(dǎo)致性能減低、死鎖、甚至不確定的行為。為了防止活性失敗和平安性失敗,在一個(gè)被同步的方法或者代碼塊中,永遠(yuǎn)不要放棄對(duì)客戶端的控制。換句話說(shuō),在一個(gè)被同步的區(qū)域內(nèi)部,不要調(diào)用設(shè)計(jì)成被覆蓋的方法,或者是由客戶端以函數(shù)的形式提供的方法。從包含該同步區(qū)域的類的角度來(lái)看,這樣的方法時(shí)外來(lái)的。這個(gè)類不知道該方法會(huì)做什么事情,也無(wú)法控制它。根據(jù)外來(lái)方法的作用,從同步區(qū)域中調(diào)用它會(huì)導(dǎo)致異常,死鎖或者數(shù)據(jù)損壞。
不要依賴于線程調(diào)度器當(dāng)有多個(gè)線程可以運(yùn)行時(shí),由線程調(diào)度器決定哪些線程將會(huì)運(yùn)行,以及運(yùn)行多長(zhǎng)時(shí)間。任何一個(gè)合理的操作系統(tǒng)〔JVM〕在做出這樣的決定時(shí),都會(huì)努力做到某種公正性,但是對(duì)于不同的JVM,其策略是不同的。一個(gè)實(shí)現(xiàn)良好的多線程程序不應(yīng)該依賴此策略的細(xì)節(jié)。不能讓應(yīng)用程序的正確性依賴于線程調(diào)度器。斗那么,結(jié)果得到的應(yīng)用程序既不健壯也不具有可移植性。作為一個(gè)推論,不要依賴Thread.yield或者線程優(yōu)先級(jí)。這些設(shè)施都只是影響到調(diào)度器,它們可以被用來(lái)提高一個(gè)已經(jīng)能夠正常工作的系統(tǒng)的效勞質(zhì)量,但永遠(yuǎn)不應(yīng)用來(lái)“修整”一個(gè)原本并不能工作的程序。編寫健壯、響應(yīng)良好的、可移植的多線程程序的最好方法是,盡可能確保在任何給定時(shí)刻只有少量的可運(yùn)行線程。這種方法采用的主要技術(shù)是,讓每個(gè)線程做少量的工作,然后使用Object.wait等待某個(gè)條件發(fā)生,或者使用Thread.sleep睡眠一段時(shí)間。防止使用線程組除了線程、鎖和監(jiān)視器之外,線程系統(tǒng)還提供了一個(gè)根本的抽象,即
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年度房地產(chǎn)營(yíng)銷推廣合同范本3篇
- 二零二五版醫(yī)療設(shè)備銷售居間代理合同樣本4篇
- 2024鋁材倉(cāng)儲(chǔ)物流服務(wù)合同范本3篇
- 二零二五年度綠色環(huán)保汽車質(zhì)押借款合同示范4篇
- 二零二五年度智能農(nóng)業(yè)技術(shù)推廣與應(yīng)用合同及99年勞動(dòng)合同補(bǔ)充2篇
- 二零二五年度項(xiàng)目合作參觀者保密合同3篇
- 2025年度新型打樁機(jī)械租賃與安全培訓(xùn)合同4篇
- 二零二五版國(guó)際貿(mào)易文化推廣合同書(shū)正規(guī)范本3篇
- 二零二五年度二手車交易合同樣本4篇
- 二零二五年度臨時(shí)用電安全風(fēng)險(xiǎn)評(píng)估與監(jiān)測(cè)服務(wù)合同
- 春節(jié)文化常識(shí)單選題100道及答案
- 12123交管學(xué)法減分考試題及答案
- 2024年杭州師范大學(xué)附屬醫(yī)院招聘高層次緊缺專業(yè)人才筆試真題
- 制造業(yè)BCM業(yè)務(wù)連續(xù)性管理培訓(xùn)
- 商場(chǎng)停車場(chǎng)管理制度
- 2025年寒假實(shí)踐特色作業(yè)設(shè)計(jì)模板
- 24年追覓在線測(cè)評(píng)28題及答案
- TGDNAS 043-2024 成人靜脈中等長(zhǎng)度導(dǎo)管置管技術(shù)
- 《陸上風(fēng)電場(chǎng)工程概算定額》NBT 31010-2019
- 藥房(冰柜)溫濕度表
- QJ903.9A-1995航天產(chǎn)品工藝文件管理制度管理用工藝文件編制規(guī)則
評(píng)論
0/150
提交評(píng)論