優(yōu)雅編程之這樣設(shè)計(jì)通用程序,你就“正?!绷耍ǘ撸?/h2>

開心一笑

【1.別人復(fù)習(xí)都是無懈可擊,學(xué)渣復(fù)習(xí)是無中生有;
2.好了老師,我們各退一步,你們別講了,我們也不聽了;
3.少一點(diǎn)作業(yè),多一顆數(shù)木;少一次考試,多一片森林;保護(hù)環(huán)境人人有責(zé)......】

提出問題

項(xiàng)目中如何編寫通用程序???

解決問題

勵(lì)志圖片

以下來自《Effective Java》中的讀書筆記:

將局部變量的作用域最小化

要是局部變量的作用域最小化,最有力的方法就是在第一次使用它的地方申明。
幾乎每個(gè)局部變量的聲明,都應(yīng)該包含一個(gè)初始化表達(dá)式。

下面是一種對(duì)局部變量的作用域進(jìn)行最小化的循環(huán)做法。

例如:

//防止每次循環(huán)都去調(diào)用size方法,提高性能
for(int i=0,len = userList.size();i < len;i++){
    .....
}

最后一種將局部變量的作用域最小化的方法是使方法小而集中。(這個(gè)在之前的文章中已經(jīng)多次提到了)

for-each循環(huán)優(yōu)于傳統(tǒng)的for循環(huán)

例如:

//不推薦
for(Iterator i=c.iterator();i.hasNext()){
    doSomething(i.next());
}
//推薦    
for(Element e:c){
    doSomething(e);
}

有三種情況無法使用for-each循環(huán):

  • 過濾:如果需要遍歷集合。并刪除選定的元素,就需要使用顯示的迭代器,以便可以調(diào)用它的remove方法。
  • 轉(zhuǎn)換:如果需要遍歷列表或者數(shù)組,并取代部分或者全部的元素值,就需要列表迭代器或者數(shù)組索引,以便設(shè)定元素的值。
  • 平行迭代:如果需要并行的遍歷多個(gè)集合,就需要顯示的控制迭代器或者索引變量,以便所有迭代器或者索引變量都可以得到同步遷移。
了解和使用類庫

盡可能的使用第三方類庫。通過使用標(biāo)準(zhǔn)類庫,可以充分利用這些編寫標(biāo)準(zhǔn)類庫的專家的知識(shí),以及在你之前的其他人的使用經(jīng)驗(yàn)。

例如:

org.apache.commons.lang3

總而言之,不要重新發(fā)明輪子,如果你要做的事情看起來是十分常見的,有可能類庫中已經(jīng)有某個(gè)類完成了這樣的工作,如果確實(shí)是這樣,就使用現(xiàn)成的。如果還不清楚是否存在這樣的類,就去查一查。

如果需要準(zhǔn)確的答案,請(qǐng)避免使用float和double

float和double類型不適合用于貨幣計(jì)算,解決辦法是使用BigDecimal,int和long進(jìn)行貨幣計(jì)算。

總而言之,對(duì)于任何需要精確答案的計(jì)算任務(wù),請(qǐng)不要使用float或者double。

基本類型優(yōu)先于裝箱基本類型

基本類型:int,double,boolean等等
引用類型:String和List等等
裝箱基本類型:Integer,Double和Boolean等等

例如:

static Integer i;
public static void main(String[] args) {
    //自動(dòng)拆箱,報(bào)NullPointerException異常
    if(i == 42){
        System.out.println("unbelievable");
    }
}

當(dāng)在一項(xiàng)操作中混合使用基本類型和裝箱基本類型時(shí),裝箱基本類型就會(huì)自動(dòng)拆箱,這種情況無一例外。

上面問題就是修正i為int類型就好了。

例如:

//這個(gè)程序存在性能問題
public static void main(String[] args) {
    Long sum = 0L;
    for(long i=0;i<Integer.MAX_VALUE;i++){
        //變量被反復(fù)的裝箱和拆箱,導(dǎo)致性能問題
        sum += i;
    }
    System.out.println(sum);
}

那么什么時(shí)候應(yīng)該使用裝箱基本類型呢?

  • 第一個(gè)是作為集合中的元素,鍵和值。
  • 第二個(gè)是在參數(shù)化類型中,必須使用裝箱基本類型作為類型參數(shù)。

總之,當(dāng)可以選擇的時(shí)候,基本類型要優(yōu)先于裝箱基本類型?;绢愋透雍?jiǎn)單,也更加快速,如果必須使用,裝箱基本類型要特別小心。自動(dòng)裝箱減少了使用裝箱基本類型的繁瑣性,但是并沒有減少它的風(fēng)險(xiǎn)。當(dāng)程序用 == 操作符比較兩個(gè)裝箱基本類型時(shí)。他做了個(gè)同一性比較,這幾乎肯定不是你所希望的。當(dāng)程序進(jìn)行涉及裝箱和拆箱基本類型的混合類型計(jì)算時(shí),他會(huì)進(jìn)行拆箱。當(dāng)程序進(jìn)行拆箱時(shí),會(huì)拋出空指針異常。最后當(dāng)程序裝箱了基本類型值時(shí),會(huì)導(dǎo)致高開銷和不必要的對(duì)象創(chuàng)建。

如果其它類型更適合,則盡量避免使用字符串
  • 字符串不適合代替其他的值類型,數(shù)值類型應(yīng)當(dāng)被適當(dāng)?shù)剞D(zhuǎn)換為數(shù)值類型,比如int,float或者double,布爾類型就應(yīng)該被轉(zhuǎn)化為boolean類型等等。
  • 字符串不適合代替枚舉類型。

例如:

String compounKey = className + "#" + i.next();

缺點(diǎn):如果用來分隔的字符也出現(xiàn)在某個(gè)域中,結(jié)果就會(huì)出現(xiàn)混亂。

  • 字符串不適合代替聚集類型。(不可偽造的鍵有時(shí)候被稱為能力)

例如:

    //有問題,在線程中,如果客戶傳入key相同,安全性就很差
    public static set(String key,Object value){
    
    }

    public static Object get(String key){
    
    }

改正:

    public static class Key{
        Key(){}
    }

    public static Key getKey(){
        return new Key();
    }
    //重點(diǎn)在這里哦,使用對(duì)象Key哦
    public static void set(Key key,Object value);

    public static Object get(Key key);
當(dāng)心字符串連接的性能

對(duì)于大規(guī)模的場(chǎng)景中,為連接n個(gè)字符串而重復(fù)的使用字符串連接操作符,需要n的平方級(jí)的時(shí)間。

具體的詳細(xì)內(nèi)容,請(qǐng)看之前的這篇文章:

優(yōu)雅編程之這樣考慮字符性能,你就“正?!绷耍ǘ?/a>

通用接口引用對(duì)象

例如:

//正確
List<Subscribe> subscribes = new Vector<>();

//欠缺
Vector<Subscribe> subscribes = new Vector<>();

當(dāng)你決定更換實(shí)現(xiàn)時(shí),所要做的就只是改變構(gòu)造器中類的名稱。

List<Subscribe> subscribes = new ArrayList<>();

周圍的所有代碼都可以繼續(xù)工作。

但是

如果沒有合適的接口存在,完全可以用類,而不是接口來引用對(duì)象。例如考慮值類,比如String和BigInteger。記住,值類很少會(huì)用多個(gè)實(shí)現(xiàn)編寫。它們通常是final
類實(shí)現(xiàn)了接口,但是它提供了接口中不存在的額外方法,如果程序依賴于這些額外的方法,這種類就應(yīng)該只被用來引用它的實(shí)例,它很少應(yīng)該被用作參數(shù)類型。

接口優(yōu)先于相射機(jī)制

反射機(jī)制需要付出代價(jià):

  • 喪失了編譯時(shí)類型檢查的好處:如果程序企圖用反射方式調(diào)用不存在或不可訪問的方法,在運(yùn)行時(shí)它將會(huì)失敗。
  • 執(zhí)行反射訪問所需要的代碼非常笨拙和冗長(zhǎng)。
  • 性能損耗。反射方法調(diào)用的比普通方法調(diào)用慢了很多。

通常普通應(yīng)用程序在運(yùn)行時(shí)不應(yīng)該以反射方式訪問對(duì)象。

謹(jǐn)慎地使用本地方法

Java Native Interface(JNI)允許Java程序可以調(diào)用本地方法(native method)

使用本地方法來提高性能的做法不值得提倡。

使用本地方法有一些嚴(yán)重的缺點(diǎn)。因?yàn)楸镜卣Z言不是安全的

謹(jǐn)慎的進(jìn)行優(yōu)化

有三條與優(yōu)化相關(guān)的格言是每個(gè)人都應(yīng)該知道的。

很多計(jì)算機(jī)上的過失都被歸咎于效率(沒有必要達(dá)到的效率),而不是任何其他的原因,甚至包括盲目地做傻事。
不要去計(jì)較效率上的一些小小的得失,在97%的情況下,不成熟的優(yōu)化才是一切問題的根源。
在優(yōu)化方面,我們應(yīng)該遵守2條原則:1.不要進(jìn)行優(yōu)化。2.(僅針對(duì)專家)還是不要進(jìn)行優(yōu)化,也就是說,在你還沒有絕對(duì)清晰的未優(yōu)化方案之前,請(qǐng)不要進(jìn)行優(yōu)化。

總之,不要費(fèi)力去編寫快速程序,應(yīng)該努力編寫好的程序,速度自然會(huì)隨之而來。

普遍接受的命名慣例
  • 包名稱:一個(gè)或者多個(gè)包的簡(jiǎn)短名稱組成,每個(gè)簡(jiǎn)短名稱通常不超過8個(gè)字符(事實(shí)發(fā)現(xiàn),JDK上的包也些也超過8個(gè)字符:java.awt.datatransfer )。所以作者在這里使用通常,也就是有例外

    java.applet
    java.awt
    java.awt.color

  • 類和接口名稱,包括枚舉和注解名稱:通常由一個(gè)或者多個(gè)單詞組成,每個(gè)單詞的首字母大寫(TimerTask),盡量避免縮寫,除非類似這種:max或者min

  • 方法和域的名稱:與類和接口名稱類似,只是方法首字母小寫。方法的名稱一般由動(dòng)詞或者動(dòng)詞,名稱組成。如:remove,removeUser等等

  • 常量:如:public static final int MIN_VALUE,全部大寫,中間用下劃線分割

  • 局部變量名稱與成員變量的名稱類似,只不過它允許縮寫

  • 類型參數(shù)名稱:通常由單個(gè)字母組成,T表示任意類型,E表示集合元素類型,K,V表示鍵和值,X表示異常

讀書感悟

來自《鄰室的音樂》

  • 窮是一種心態(tài),你若一輩子堅(jiān)持自己是窮人,擁有大量金錢也救不了你。
  • 凡是太好的東西都不像真的。又有人說,如果一件事好得不似真的,可能它的確不是真的。
  • 人生試題一共四道題目。學(xué)業(yè)事業(yè)婚姻家庭,平均分高才能及格,切莫花太多時(shí)間在任何一題上。
  • 真正聰明的女子該是懂得利用自己的智慧享受生命,而不僅僅是為了那點(diǎn)生不帶來死不帶去的利益。這點(diǎn)沒有想通,便失去了自我,失去了珍貴的友誼。

其他

如果有帶給你一絲絲小快樂,就讓快樂繼續(xù)傳遞下去,歡迎轉(zhuǎn)載,點(diǎn)贊,頂,歡迎留下寶貴的意見,多謝支持!

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,525評(píng)論 19 139
  • 國家電網(wǎng)公司企業(yè)標(biāo)準(zhǔn)(Q/GDW)- 面向?qū)ο蟮挠秒娦畔?shù)據(jù)交換協(xié)議 - 報(bào)批稿:20170802 前言: 排版 ...
    庭說閱讀 12,321評(píng)論 6 13
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,633評(píng)論 18 399
  • 1.關(guān)于RabbitMQ## RabbitMQ是一個(gè)開源的消息代理和隊(duì)列服務(wù)器,用來通過普通協(xié)議在完全不同的應(yīng)用之...
    樸下柔閱讀 10,757評(píng)論 5 18
  • 兒子,業(yè)余時(shí)間能成就一個(gè)人,也能毀滅一個(gè)人,人的成就和差異有時(shí)就取決于業(yè)余時(shí)間。每個(gè)人在校時(shí)間學(xué)習(xí)都差不多,更重要...
    聽雨聆聲閱讀 2,547評(píng)論 2 7

友情鏈接更多精彩內(nèi)容