Java學習筆記 17 - 異常及異常處理

本文主要內容
1、異常以及處理方式
2兼贸、運行時期異常
3段直、方法重寫的異常處理
4、Throwable類常見方法
5溶诞、自定義異常

01異常

A鸯檬、異常概述
異常:代碼在運行時期產生的問題。
在Java中螺垢,把異常信息封裝成了一個類喧务。
當程序出現(xiàn)問題赖歌,即創(chuàng)建異常類對象并拋出異常相關的信息(如異常出現(xiàn)的位置、原因等)功茴。
常見的異常:數組角標越界異常ArrayIndexOutOfBoundsException,空指針異常NullPointerException

B庐冯、異常的繼續(xù)體系
Throwable: 它是所有錯誤與異常的超類(祖宗類)
|- Error 錯誤
|- Exception 編譯期異常,進行編譯JAVA程序時出現(xiàn)的問題
|- RuntimeException 運行期異常, JAVA程序運行過程中出現(xiàn)的問題
C、異常與錯誤
a:異常
* 指程序在編譯坎穿、運行期間發(fā)生了某種異常(XxxException)展父,我們可以對異常進行具體的處理。
* 若不處理異常玲昧,程序將會結束運行栖茉。

            public static void main(String[] args) {
                int[] arr = new int[3];
                System.out.println(arr[0]);
                System.out.println(arr[3]);
                // 該句運行時發(fā)生了數組索引越界異常ArrayIndexOutOfBoundsException,
                // 由于沒有處理異常酌呆,導致程序無法繼續(xù)執(zhí)行衡载,程序結束搔耕。
                System.out.println("over"); // 由于上面代碼發(fā)生了異常隙袁,此句代碼不會執(zhí)行
            }
            
b:錯誤
        指程序在運行期間發(fā)生了某種錯誤(XxxError),Error錯誤通常沒有具體的處理方式弃榨,程序將會結束運行菩收。
        Error錯誤的發(fā)生往往都是系統(tǒng)級別的問題,都是jvm所在系統(tǒng)發(fā)生的鲸睛,并反饋給jvm娜饵。
        錯誤無法處理,只能修正代碼官辈。
    
            public static void main(String[] args) {
                int[] arr = new int[1024*1024*100];
                //該句運行時發(fā)生了內存溢出錯誤OutOfMemoryError箱舞,開辟了過大的數組空間,
                //導致JVM在分配數組空間時超出了JVM內存空間拳亿,直接發(fā)生錯誤晴股。
            }

D:異常對象的產生原因和處理方式
a: 異常對象的產生原因

  • 工具類

          class ArrayTools{
              //對給定的數組通過給定的角標獲取元素。
              public static int getElement(int[] arr,int index)   {
                  int element = arr[index];
                  return element;
              }
          }
    
  • 測試類

          class ExceptionDemo2 {
              public static void main(String[] args)  {
                  int[] arr = {34,12,67};
                  int num = ArrayTools.getElement(arr,4)
                  System.out.println("num="+num);
                  System.out.println("over");
              }
          }
    
  • 原因分析:

  • 1: 由于沒找到4索引肺魁,導致運行時發(fā)生了異常电湘。這個異常JVM認識:ArrayIndexOutOfBoundsException。
    這個異常Java本身有描述:異常的名稱鹅经、異常的內容寂呛、異常的產生位置。
    java將這些信息直接封裝到異常對象中瘾晃。new ArrayIndexOutOfBoundsException(4);

  • 2:throw new ArrayIndexOutOfBoundsException(4);產生異常對象贷痪。JVM將產生的異常拋給調用者main()方法。

  • 3:main()方法接收到了數組索引越界異常對象蹦误。
    由于main()方法并沒有進行處理異常呢诬,main()方法就會繼續(xù)把異常拋給調用者JVM涌哲。
    當JVM收到異常后,將異常對象中的名稱尚镰、異常內容阀圾、位置都顯示在就控制臺上。同時讓程序立刻終止狗唉。

b:異常的處理方式
1:JVM的默認處理方式
把異常的名稱,原因,位置等信息輸出在控制臺初烘,同時會結束程序。
一旦有異常發(fā)生分俯,其后來的代碼不能繼續(xù)執(zhí)行肾筐。
2:解決程序中異常的手動方式
a):編寫處理代碼 try...catch...finally
b):拋出 throws

02 方法內部拋出對象throw關鍵字

在java中,提供了一個throw關鍵字缸剪,它用來拋出一個指定的異常對象吗铐。
A: 什么時候使用throw關鍵字?
當調用方法使用接受到的參數時杏节,首先需要先對參數數據進行合法的判斷唬渗,
數據若不合法,就應該告訴調用者奋渔,傳遞合法的數據進來镊逝。
這時需要使用拋出異常的方式來告訴調用者。

B: 使用throw關鍵字具體操作
a: 創(chuàng)建一個異常對象嫉鲸。封裝一些提示信息(信息可以自己編寫)撑蒜。
b: 通過關鍵字throw將這個異常對象告知給調用者。throw 異常對象玄渗;
throw 用在方法內座菠,用來拋出一個異常對象,將這個異常對象傳遞到調用者處藤树,并結束當前方法的執(zhí)行浴滴。

C: throw關鍵字使用格式
throw new 異常類名(參數);
例如:
throw new NullPointerException("要訪問的arr數組不存在");
throw new ArrayIndexOutOfBoundsException("該索引在數組中不存在,已超出范圍");

03方法聲明異常關鍵字throws

A: 聲明
將問題標識出來也榄,報告給調用者巡莹。如果方法內通過throw拋出了編譯時異常,而沒有捕獲處理(稍后講解該方式)甜紫,那么必須通過throws進行聲明降宅,讓調用者去處理。

B: 聲明異常格式
修飾符 返回值類型 方法名(參數) throws 異常類名1,異常類名2… { }

C:注意事項:
throws用于進行異常類的聲明囚霸,若該方法可能有多種異常情況產生腰根,那么在throws后面可以寫多個異常類,用逗號隔開拓型。

04 try...catch異常處理

A: 捕獲
Java中對異常有針對性的語句進行捕獲额嘿,可以對出現(xiàn)的異常進行指定方式的處理
B: 捕獲異常格式

    try {
        //需要被檢測的語句瘸恼。
    }
    catch(異常類 變量) { //參數。
        //異常的處理語句册养。
    }
    finally {
        //一定會被執(zhí)行的語句东帅。
    }

C: 格式說明
a: try
* 該代碼塊中編寫可能產生異常的代碼。
b: catch
* 用來進行某種異常的捕獲球拦,實現(xiàn)對捕獲到的異常進行處理靠闭。
c: finally:
* 有一些特定的代碼無論異常是否發(fā)生,都需要執(zhí)行坎炼。
* 另外愧膀,因為異常會引發(fā)程序跳轉,導致有些語句執(zhí)行不到谣光。
* 而finally就是解決這個問題的檩淋,在finally代碼塊中存放的代碼都是一定會被執(zhí)行的。
d:try...catch...處理掉異常后萄金,程序可以繼續(xù)執(zhí)行

05 多catch處理

A:一個try 多個catch組合
* 對代碼進行異常檢測蟀悦,并對檢測的異常傳遞給catch處理。對每種異常信息進行不同的捕獲處理捡絮。
B:多catch處理的格式

    void show(){ //不用throws 
        try{
            throw new Exception();//產生異常熬芜,直接捕獲處理
        }catch(XxxException e){
            //處理方式  
        }catch(YyyException e){
            //處理方式  
        }catch(ZzzException e){
            //處理方式  
        }
    }

    注意事項:在捕獲異常處理中莲镣,變量也是有作用域的福稳,如可以定義多個catch中異常變量名為e。

C:多catch處理細節(jié)
a:細節(jié):多個catch小括號中瑞侮,寫的是異常類的類名的圆,有沒有順序的概念?
有順序關系半火。

b:平級異常:
拋出的異常類之間,沒有繼承關系,沒有順序
NullPointerException extends RuntimeException
NoSuchElementException extends RuntimeException
ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException extends RuntimeException

c:上下級關系的異常
越高級的父類,越寫在下面
NullPointerException extends RuntimeException extends Exception

06 finally代碼塊

A: finally的特點
被finally控制的語句體一定會執(zhí)行

B:finally的作用
finally,無論程序是否有異常出現(xiàn),程序必須執(zhí)行
如:IO流操作和數據庫操作

07 運行時期異常的特點

A: 運行時期異常的概述:
RuntimeException和他的所有子類異常,都屬于運行時期異常越妈。
NullPointerException,ArrayIndexOutOfBoundsException等都屬于運行時期異常.

B:運行時期異常的特點
a:方法中拋出運行時期異常,方法定義中無需throws聲明,調用者也無需處理此異常。
b:運行時期異常一旦發(fā)生,需要程序人員修改源代碼钮糖。
設計原因:
運行異常,不能發(fā)生,但是如果發(fā)生了,程序人員停止程序修改源代碼
運行異常: 一旦發(fā)生,不要處理,請你修改源代碼,運行異常一旦發(fā)生,后面的代碼沒有執(zhí)行的意義

08 方法重寫時候異常的處理

A:方法重寫時候異常的處理
a:子類覆蓋父類方法時梅掠,如果父類的方法聲明異常,子類只能聲明父類異车旯椋或者該異常的子類阎抒,或者不聲明。
例如:

        class Fu {
            public void method () throws RuntimeException {
            }
        }
        class Zi extends Fu {
            public void method() throws RuntimeException { }  //拋出父類一樣的異常
            //public void method() throws NullPointerException{ } //拋出父類子異常
        }

b:當父類方法聲明多個異常時消痛,子類覆蓋時只能聲明多個異常的子集且叁。

        class Fu {
            public void method () throws NullPointerException, ClassCastException{
            }
        }
        class Zi extends Fu {
            public void method()throws NullPointerException, ClassCastException { }         
            public void method() throws NullPointerException{ } //拋出父類異常中的一部分
            public void method() throws ClassCastException { } //拋出父類異常中的一部分
        }

c:當被覆蓋的方法沒有異常聲明時,子類覆蓋時無法聲明異常的秩伞。

        class Fu {
            public void method (){
            }
        }
        class Zi extends Fu {
            public void method() throws Exception { }//錯誤的方式
        }

B:問題:父類中會存在下列這種情況逞带,接口也有這種情況欺矫。
接口中沒有聲明異常,而實現(xiàn)的子類覆蓋方法時發(fā)生了異常展氓,怎么辦穆趴?
回答:無法進行throws聲明,只能catch的捕獲遇汞。
萬一問題處理不了呢毡代?catch中繼續(xù)throw拋出,但是只能將異常轉換成RuntimeException子類拋出勺疼。

09 Throwable類方法

a:getMessage()方法
返回該異常的詳細信息字符串教寂,即異常提示信息
b:toString()方法
返回該異常的名稱與詳細信息字符串
c:printStackTrace()方法
在控制臺輸出該異常的名稱與詳細信息字符串、異常出現(xiàn)的代碼位置

        try {
            Person p= null;
            if (p==null) {
                throw new NullPointerException(“出現(xiàn)空指針異常了执庐,請檢查對象是否為null”);
            }
        } catch (NullPointerException e) {
            String message = e.getMesage();
            System.out.println(message ); 
            
            String result = e.toString();
            System.out.println(result); 
            
            e.printStackTrace(); 
        }

10自定義異常

A: 自定義異常的定義
a:通過閱讀源碼酪耕,發(fā)現(xiàn)規(guī)律:
每個異常中都調用了父類的構造方法,把異常描述信息傳遞給了父類轨淌,讓父類幫我們進行異常信息的封裝迂烁。
b:格式:

    Class 異常名 extends Exception{ //或繼承RuntimeException
            public 異常名(){
            }
            public 異常名(String s){ 
                super(s); 
            }
        }   

c:自定義異常繼承Exception演示
d:自定義異常繼承RuntimeException演示

B:自定義異常的練習
在Person類的有參數構造方法中,進行年齡范圍的判斷递鹉,
若年齡為負數或大于200歲盟步,則拋出NoAgeException異常,異常提示信息“年齡數值非法”躏结。
要求:在測試類中却盘,調用有參數構造方法,完成Person對象創(chuàng)建媳拴,并進行異常的處理黄橘。

C:關于構造方法拋出異常總結
構造函數到底拋出這個NoAgeException是繼承Exception呢屈溉?還是繼承RuntimeException呢塞关?
a:繼承Exception,必須要throws聲明子巾,一聲明就告知調用者進行捕獲帆赢,一旦問題處理了調用者的程序會繼續(xù)執(zhí)行忍饰。
b:繼承RuntimeExcpetion,不需要throws聲明的叉抡,這時調用是不需要編寫捕獲代碼的,因為調用根本就不知道有問題萍肆。
一旦發(fā)生NoAgeException缠导,調用者程序會停掉廉羔,并有jvm將信息顯示到屏幕,讓調用者看到問題,修正代碼憋他。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末孩饼,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子竹挡,更是在濱河造成了極大的恐慌镀娶,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件揪罕,死亡現(xiàn)場離奇詭異梯码,居然都是意外死亡,警方通過查閱死者的電腦和手機好啰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進店門轩娶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人框往,你說我怎么就攤上這事鳄抒。” “怎么了椰弊?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵许溅,是天一觀的道長。 經常有香客問我秉版,道長贤重,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任清焕,我火速辦了婚禮并蝗,結果婚禮上,老公的妹妹穿的比我還像新娘耐朴。我一直安慰自己借卧,他們只是感情好盹憎,可當我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布筛峭。 她就那樣靜靜地躺著,像睡著了一般陪每。 火紅的嫁衣襯著肌膚如雪影晓。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天檩禾,我揣著相機與錄音挂签,去河邊找鬼。 笑死盼产,一個胖子當著我的面吹牛饵婆,可吹牛的內容都是我干的。 我是一名探鬼主播戏售,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼侨核,長吁一口氣:“原來是場噩夢啊……” “哼草穆!你這毒婦竟也來了?” 一聲冷哼從身側響起搓译,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤悲柱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后些己,有當地人在樹林里發(fā)現(xiàn)了一具尸體豌鸡,經...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年段标,在試婚紗的時候發(fā)現(xiàn)自己被綠了涯冠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡逼庞,死狀恐怖功偿,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情往堡,我是刑警寧澤械荷,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站虑灰,受9級特大地震影響吨瞎,放射性物質發(fā)生泄漏。R本人自食惡果不足惜穆咐,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一颤诀、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧对湃,春花似錦崖叫、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至拆讯,卻和暖如春脂男,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背种呐。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工宰翅, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人爽室。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓汁讼,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子嘿架,可洞房花燭夜當晚...
    茶點故事閱讀 44,941評論 2 355