常見Java缺陷模式

面對(duì)Java問題的定位-表現(xiàn)得不那么自信衡招,有時(shí)我在想是我把問題想的太難篱昔,還是問題本身就難,還是我沒有專心去看代碼...始腾,因?yàn)榭偪傊莨簦袝r(shí)還沒有看到真正的問題,就陣亡啦浪箭,想來死得好冤呀穗椅。

本文屬于《軟件缺陷模式與測(cè)試》的讀書摘要,感謝作者們辛苦寫書奶栖,受益良多匹表,書中對(duì)Java故障模式進(jìn)行了總結(jié),分6大類宣鄙,對(duì)每個(gè)故障形成原因袍镀、表現(xiàn)形式進(jìn)行分析,并給出了解決方案冻晤,值得細(xì)細(xì)閱讀苇羡,去體會(huì)示例代碼,相信讀后再看到程序報(bào)錯(cuò)鼻弧,會(huì)多那么點(diǎn)底氣设江。

  1. 空指針
    日志:NullPointerException
    表現(xiàn)在:
  1. 可能為null的引用變量
    增加是否為null的判斷
  2. 不完全的null條件判斷
    判斷邏輯不嚴(yán)謹(jǐn)锦茁,前面雖判斷了是否為null,但是其他地方又用到該對(duì)象--修改判斷邏輯
  3. 函數(shù)返回值可能為null
    list.getNext().dosomething() --list.getNext()為null
    使用返回值前 先做判斷
  4. 函數(shù)返回值是數(shù)組類型時(shí)返回null
return new string[0]; 
改成 
return null;
  1. 所調(diào)用函數(shù)的參數(shù)約束為not null
if ( getClass() != obj.getClass() ) 
#如果obj為null绣硝,則拋出異常
  1. 重載equals 方法時(shí)沒有處理好參數(shù)null的情況
    總結(jié):獲取到的對(duì)象有可能為null,在使用前最好先做判斷蜻势,不為null,才做下一步。
  1. 數(shù)組越界
    基礎(chǔ)知識(shí):數(shù)組的下標(biāo)index從(0--數(shù)組長(zhǎng)度-1)
    即是:數(shù)組長(zhǎng)度為2鹉胖,數(shù)組兩個(gè)值array_name[0]握玛、array_name[1]
    任何index小于0,大于數(shù)組長(zhǎng)度-1的-都會(huì)拋出數(shù)組越界
    日志:ArrayIndexOutOfBoundsException
    1)顯示指定數(shù)組長(zhǎng)度甫菠,數(shù)組使用越界
 public void arrayStudy(){
        int max_len = 4;
        int[] array = new int[max_len];
        for (int i=0; i<= max_len; i++){
            array[i] = i;   
        }
    }
#當(dāng)array[4]時(shí)報(bào)
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 4
    at pers.qingqian.study.eight.ErrorStudy.arrayStudy(ErrorStudy.java:32)
    at pers.qingqian.study.eight.ErrorStudy.main(ErrorStudy.java:38)
  1. 隱式指定數(shù)組長(zhǎng)度挠铲,數(shù)組使用越界
    public void arrayStudy(){
        int max_len = 4;
    //    int[] array = new int[max_len];
        int[] array = new int[]{1,2,3,4};
        for (int i=0; i<= max_len; i++){
            array[i] = i;
        }
    }

3)使用數(shù)組,length方法不當(dāng)寂诱,數(shù)組使用越界
4)多維數(shù)組越界
總結(jié):index只要在0-length-1內(nèi)拂苹,不管是一維還是二維都不會(huì)有數(shù)組越界

  1. 資源泄漏
    基礎(chǔ)知識(shí):指的是封裝了類似文件句柄、Socket痰洒、數(shù)據(jù)庫(kù)連接瓢棒、圖形界面對(duì)象等這樣的操作系統(tǒng)底層資源的對(duì)象被使用后,沒有被顯性的釋放-及時(shí)將其回收丘喻。
  1. 函數(shù)內(nèi)部資源泄漏
    public void printLines(String fName,Line lines){
      try{
           File file = new File(fName);
           PrintWriter pstr = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));
          ... 省略N行代碼
      }catch (IOException e){
            e.printStackTrace();
      }
     }
修改成
    public void printLines(String fName,Line lines){
        PrintWriter pstr = null;
      try{
           File file = new File(fName);
           pstr = new PrintWriter(new BufferedOutputStream(new FileOutputStream(file)));
            ... 省略N行代碼
      }catch (IOException e){
            e.printStackTrace();
      }finally{
          pstr.close();
      }
     }

2)異常路徑導(dǎo)致的資源泄漏

public void f() throws FileNotFoundException, IOException {
       FileOutputStream e = null;
       try {
           e = new FileOutputStream("C:\test.java");
           e.write(20);
           e.close();
       }
       finally {}// Defect
   }

當(dāng)程序運(yùn)行到e.write(20)拋出異常后脯宿,e.close()將不會(huì)被執(zhí)行。
3)私有域資源不能釋放導(dǎo)致泄漏
4)函數(shù)間調(diào)用產(chǎn)生的資源泄漏
簡(jiǎn)單的講:A方法中中new了一個(gè)資源泉粉,沒有寫釋放连霉,直接將資源傳遞給B方法,B方法也沒有是否該資源的地方
5)包裝類構(gòu)造方法出錯(cuò)可能造成資源泄漏
總結(jié):不管出的現(xiàn)象怎么變嗡靡,都是一個(gè)原因跺撼,創(chuàng)建了可和底層操作相關(guān)的對(duì)象時(shí) 就必須有釋放該對(duì)象的方法,否則就會(huì)產(chǎn)生資源泄漏讨彼。
附:JDK庫(kù)中資源分配和釋放需要注意的問題

  1. 在JDK庫(kù)中有一些修飾類-不是資源歉井,但它們的構(gòu)造方法中可能包裝了一個(gè)資源。調(diào)用這些類的釋放函數(shù)哈误,也釋放了內(nèi)部包裝的資源哩至。
    2)不同的資源使用不同的釋放函數(shù)close、dispose黑滴、disconnect
    3)不用資源具有不同的分配方式
    4)釋放函數(shù)為close
FileOutputStream
FilterOutputStream
...
#這類最多

5)釋放函數(shù)為dispose

StreamPrintService
CompositeContext
Graphics
InputContext
InputMethod
PaintContext
Window

6)釋放函數(shù)為disconnect

HttpURLConnection

7)其他分配方式

getConnection
createStatement
executeQuery
getResultSet
prepareStatement
prepareCall
accept

8)可能被包裝的非資源類

ByteArrayOutputStream

9)可能被包裝的資源類

FileOutputStream
  1. 非法計(jì)算
  1. 除法或取余運(yùn)算的第二個(gè)操作數(shù)可能為0
    2)常用的數(shù)學(xué)函數(shù)參數(shù)超出其定義范圍
    如:asin(x) --- -1 <=x <=1
  1. 死循環(huán)
  1. 循環(huán)語(yǔ)句中的死循環(huán)結(jié)構(gòu)
  2. while語(yǔ)句中的死循環(huán)結(jié)構(gòu)
  3. do-while語(yǔ)句中的死循環(huán)結(jié)構(gòu)
  4. 函數(shù)遞歸調(diào)用造成的死循環(huán)
    當(dāng)真有死循環(huán)時(shí)非常容易發(fā)現(xiàn)的憨募,只要訪問到死循環(huán)代碼,你就會(huì)發(fā)現(xiàn)CPU超級(jí)高袁辈,去看下線程就能找到是哪里死循環(huán)啦菜谣。
  1. 并發(fā)
    線程并發(fā)問題導(dǎo)致的缺陷模式
  1. 不正確的同步
  2. 死鎖
  3. 多線程應(yīng)用中方法調(diào)用時(shí)機(jī)或方式不正確
  4. 同一變量的雙重驗(yàn)證
 public static Singleton getInstance(){
        if ( instance == null ){
            synchronized (Singleton.class) {
                if ( instance == null )
                    instance = new Singleton();                
            }           
        }
        return instance;
    }

線程1已運(yùn)行到 instance = new Singleton(); ,被線程2搶占CPU,線程2運(yùn)行 因instance不為null,返回對(duì)象尾膊。
由于instance已經(jīng)被分配了內(nèi)存空間媳危,但沒有初始化數(shù)據(jù),因此利用線程2返回的instance做操作時(shí)會(huì)出現(xiàn)失敗或異常冈敛。

  1. 相互初始化的類
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末待笑,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子抓谴,更是在濱河造成了極大的恐慌暮蹂,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,839評(píng)論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件癌压,死亡現(xiàn)場(chǎng)離奇詭異仰泻,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)滩届,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,543評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門集侯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人帜消,你說我怎么就攤上這事棠枉。” “怎么了泡挺?”我有些...
    開封第一講書人閱讀 153,116評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵辈讶,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我粘衬,道長(zhǎng)荞估,這世上最難降的妖魔是什么咳促? 我笑而不...
    開封第一講書人閱讀 55,371評(píng)論 1 279
  • 正文 為了忘掉前任稚新,我火速辦了婚禮,結(jié)果婚禮上跪腹,老公的妹妹穿的比我還像新娘褂删。我一直安慰自己,他們只是感情好冲茸,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,384評(píng)論 5 374
  • 文/花漫 我一把揭開白布屯阀。 她就那樣靜靜地躺著,像睡著了一般轴术。 火紅的嫁衣襯著肌膚如雪难衰。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,111評(píng)論 1 285
  • 那天逗栽,我揣著相機(jī)與錄音盖袭,去河邊找鬼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛鳄虱,可吹牛的內(nèi)容都是我干的弟塞。 我是一名探鬼主播,決...
    沈念sama閱讀 38,416評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼拙已,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼决记!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起倍踪,我...
    開封第一講書人閱讀 37,053評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤系宫,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后建车,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體笙瑟,經(jīng)...
    沈念sama閱讀 43,558評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,007評(píng)論 2 325
  • 正文 我和宋清朗相戀三年癞志,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了往枷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,117評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡凄杯,死狀恐怖错洁,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情戒突,我是刑警寧澤屯碴,帶...
    沈念sama閱讀 33,756評(píng)論 4 324
  • 正文 年R本政府宣布,位于F島的核電站膊存,受9級(jí)特大地震影響导而,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜隔崎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,324評(píng)論 3 307
  • 文/蒙蒙 一今艺、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爵卒,春花似錦虚缎、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,315評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至轴合,卻和暖如春创坞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背受葛。 一陣腳步聲響...
    開封第一講書人閱讀 31,539評(píng)論 1 262
  • 我被黑心中介騙來泰國(guó)打工题涨, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留豪椿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 45,578評(píng)論 2 355
  • 正文 我出身青樓携栋,卻偏偏與公主長(zhǎng)得像搭盾,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子婉支,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,877評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法鸯隅,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法向挖,繼承相關(guān)的語(yǔ)法蝌以,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 31,587評(píng)論 18 399
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理何之,服務(wù)發(fā)現(xiàn)跟畅,斷路器,智...
    卡卡羅2017閱讀 134,600評(píng)論 18 139
  • 對(duì)象的創(chuàng)建與銷毀 Item 1: 使用static工廠方法溶推,而不是構(gòu)造函數(shù)創(chuàng)建對(duì)象:僅僅是創(chuàng)建對(duì)象的方法徊件,并非Fa...
    孫小磊閱讀 1,963評(píng)論 0 3
  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司蒜危,掛了不少虱痕,但最終還是拿到小米概而、百度狈孔、阿里柬唯、京東陕贮、新浪、CVTE怔软、樂視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,192評(píng)論 11 349
  • 人生充滿未知姜性,以畫思人猪叙!
    齔繪閱讀 162評(píng)論 2 2