異常

一、異常的產(chǎn)生

先看下面的這個(gè)demo:

/*
 * 異常的產(chǎn)生
 */

public class ExceptionDemo {
    public static void main(String[] args) {
        System.out.println(0/0);
        System.out.println("hello world");
    }
}

此時(shí)程序就產(chǎn)生 的異常如下:

Exception in thread "main" java.lang.ArithmeticException: / by zero
    at exceptions.ExceptionDemo.main(ExceptionDemo.java:11)

分析:

  • JVM檢測(cè)到了問題(0是除數(shù)的問題),于是程序發(fā)生了異常
  • JVM就把這個(gè)異常進(jìn)行了對(duì)象的封裝new ArithmeticException()
  • 異常對(duì)象被拋給調(diào)用者main中,main方法接收到這個(gè)異常后萧锉,由于程序中沒有對(duì)異常進(jìn)行處理的方法,因此mian方法也不能處理此異常,于是異常又被拋出到JVM中
  • JVM接受到異常后茴丰,采取了默認(rèn)的處理措施,停止運(yùn)行程序天吓,于是后面的這個(gè)syso語句沒有執(zhí)行贿肩。

異常也是對(duì)象,上述例子中異常對(duì)象的描述類是ArithmeticException龄寞,它是用來描述數(shù)學(xué)中算數(shù)問題的 異常類汰规。比如還有常見的空指針異常描述類NullPointerException。

二物邑、異常的繼承體系

Throwable類是所有異常和錯(cuò)誤的父類

  • Error 錯(cuò)誤

  • Exception 異常

    錯(cuò)誤:程序出現(xiàn)了嚴(yán)重的問題溜哮,不修改代碼,根本不能運(yùn)行拂封,人得了非典茬射,艾滋,癌

    異常:程序出現(xiàn)了比較輕的問題冒签,處理掉之后在抛,繼續(xù)運(yùn)行,人得了闌尾炎萧恕,感冒

Exception類是所有異常的父類

  • 非RuntimeException
  • RuntimeException

Throwable中的方法:

  • String toString()重寫Object類的方法刚梭,異常信息的詳細(xì)描述?
  • String getMessage() 返回異常信息的簡短描述
  • void printStackTrace() 異常信息輸出到控制臺(tái)

三肠阱、異常的兩種處理方式

  1. 直接處理掉異常

    demo:

    try{
      嘗試捕獲異常的代碼
    }catch(異常類 異常變量){
      異常處理代碼
    }
    
  2. 第二種處理方式就是拋出異常

    • throw 手動(dòng)拋出異常,后面寫的是new異常的對(duì)象朴读,寫在方法中
    • throws 方法聲明拋出異常屹徘,后面寫的是異常類,寫在方法的聲明上

    demo:

    /*
      異常第二種處理方式衅金,拋出異常
      throw throws的用法
    
      ExceptionDemo2.java:21: 錯(cuò)誤: 未報(bào)告的異常錯(cuò)誤Exception; 必須對(duì)其進(jìn)行捕獲或聲明
      以便拋出
          throw new Exception();
      方法中噪伊,有異常拋出,但是沒有處理過氮唯,因此編譯失敗
      異常的編譯提示鉴吹,是Java編譯時(shí)的最后提示
    */
    
    class ExceptionDemo2 
    {
     public static void main(String[] args) throws Exception
     {
         //System.out.println("Hello World!");
         //main中調(diào)用了method方法,方法拋出了異常
         //main有2個(gè)選擇方法惩琉,一個(gè)是try...catch
         //另外一個(gè)是豆励,異常我也不處理,交給我的調(diào)用者處理
         method(-5);
     }
     /*
        如果方法的參數(shù)小于0
        程序出現(xiàn)異常瞒渠,如果參數(shù)大于0 良蒸,程序是正常的
        方法自己,不想處理這個(gè)異常伍玖,把異常交給調(diào)用者處理
        在方法聲明上嫩痰,拋出異常,聲明出來有異常私沮,交給調(diào)用者
        throws 異常類
     */
     public static void method(int x)throws Exception{
        if(x < 0)
            //程序出現(xiàn)了問題
            //手動(dòng)拋出異常
            throw new Exception("程序出現(xiàn)了異常了");
         
         else
             System.out.println("程序正常");
     }
    }
    

四始赎、多層異常的處理

demo

/*
  多層的異常處理方法調(diào)用
*/

class ExceptionDemo3 
{
    public static void main(String[] args) 
    {
        //System.out.println("Hello World!");
        try{
        methodA();
        }catch(Exception e){
        
        }
    }

    public static void methodA()throws Exception{
       methodB();
    }

    public static void methodB()throws Exception{
        methodC();
    }

    public static void methodC()throws Exception{
       throw new Exception();
    }
}

五、finally代碼塊

  • finally可以跟隨try出現(xiàn)仔燕,也可以跟隨try...catch出現(xiàn)
  • finally代碼塊中的程序造垛,必須要運(yùn)行
  • finally實(shí)際的開發(fā)意義,釋放資源

demo

/*
   finally代碼塊
   一定要執(zhí)行
*/

class ExceptionDemo4 
{
    public static void main(String[] args) 
    {
        try{
        method(1);
        }catch(Exception e){
           e.printStackTrace();
        }finally{
            System.out.println("這里的程序必須執(zhí)行");
        }
    }

    public static void method(int x)throws Exception{
       if(x == 1)
           throw new Exception("異常了!!");
       else
           System.out.println("程序正常了");
    }
}

一個(gè)finally的特例:

/*
demo:true or false
*/
class ExceptionDemo5{
  public static void main(String[] args){
    System.out.println(method());
  }
  public static boolean method(){
    
    try{
      return false;
    }catch(Exception e){
      
    }finally{
      return true;
    }
  }
}
//結(jié)果:true


/*
demo2:2 or 10
開發(fā)中晰搀,不要再try catch中寫return
*/
class ExceptionDemo6{
  public static void main(String[] args){
    System.out.println(method());
  }
  public static int method(){
    int i = 1;
    try{
      return ++i;
    }catch(Exception e){
      return 100;
    }finally{
       i=10;
    }
  }
}
//結(jié)果:2

六五辽、編譯時(shí)期的異常

調(diào)用一個(gè)方法,這個(gè)方法拋出一個(gè)異常外恕,此時(shí)調(diào)用者必須處理異常杆逗,否則編譯失敗。

Demo

/*
   編譯時(shí)期的異常 
*/
class ExceptionDemo2{
    public static void main(String[] args){
        System.out.printf("hello wordl");
        method();
    }

    public static void method() throws Exception{}
}

結(jié)果如下:

ExceptionDemo2.java:10: 錯(cuò)誤: 未報(bào)告的異常錯(cuò)誤Exception; 必須對(duì)其進(jìn)行捕獲或聲明
以便拋出
        method();
              ^
1 個(gè)錯(cuò)誤

改進(jìn)鳞疲,加上try catch對(duì)異常進(jìn)行處理罪郊,錯(cuò)誤提示消失。

/*
   編譯時(shí)期的異常 
*/

class ExceptionDemo2{
    public static void main(String[] args){
        System.out.printf("hello wordl");
        try{
        method();
        }catch(Exception e){}
    }

    public static void method() throws Exception{}
}

七尚洽、運(yùn)行時(shí)期的異常

運(yùn)行時(shí)期的異常一旦發(fā)生了悔橄,后面的所有程序都不會(huì)接著往下執(zhí)行,所以設(shè)計(jì)運(yùn)行時(shí)期的異常的初衷就很明顯了,這個(gè)異常就是讓開發(fā)人員看的癣疟,發(fā)生運(yùn)行異常挣柬,就必須去修改原代碼,而不是去處理異常睛挚。

Demo

/*
  運(yùn)行時(shí)期的異常的特點(diǎn)
*/
class ExceptionDemo3{
    public static void main(String[] args){
        //調(diào)用者不知道方法會(huì)出現(xiàn)異常邪蛔,所以就不用處理
        //這種時(shí)候,需要修改代碼扎狱,而不需要處理
        method();
    }

    public static  void method(){
        //手動(dòng)拋出一個(gè)異常

        throw new RuntimeException();
    }
}

Demo2

/*
  要求:計(jì)算正方形面積侧到,邊長的平方
  定義方法:求面積,返回結(jié)果
*/
class ExceptionDemo4{
    public static void main(String[] args){
        
        System.out.println(method(-8));
    }

    public static  int method(int num){
        if(num <= 0){
            //邊長不合法淤击,沒有必要計(jì)算
            throw new RuntimeException("<= 0");
        }
        return num * num;
    }
}

常見的運(yùn)行時(shí)期的異常:

異常對(duì)象 實(shí)際含義
IndexOutOfBoundsException 越界(字符串床牧,和數(shù)組)
NullPointerException 空指針
ClassCastException 類型轉(zhuǎn)換異常
NoSuchElementException 沒有元素被取出
IllegalArgumentException 無效參數(shù)異常

八、自定義異常

Java中異常體系遭贸,將很多的情況都做了異常封裝,但是實(shí)際的開發(fā)中心软,不可能把所有的異常都描述完畢壕吹,需要自定義的異常,用來描述自己程序中可能發(fā)生的異常删铃。

自定義異常步驟:

  1. 定義類耳贬,后綴名Exception繼承Exception類,或者繼承RuntimeException
  2. 異常信息猎唁,自定義的異常類的構(gòu)造方法咒劲,把異常信息使用super傳遞到父類

注意:只有異常類,才具備可拋性 throw new 異常體系的類

通過剛才案例:

  1. 如果一個(gè)方法中诫隅,拋出多個(gè)異常腐魂,必須要throws聲明多個(gè)異常(運(yùn)行時(shí)起除外)
  2. 調(diào)用者,使用多個(gè)catch進(jìn)行異常的捕獲
  3. 多個(gè)catch中逐纬,最大(繼承關(guān)系)的父類蛔屹,寫在最后面,否則編譯失敗

Demo

package exceptions;

/*
 * 自定義異常
 */

//負(fù)數(shù)異常
class FuShuException extends Exception{
     FuShuException(){}

     FuShuException(String info){
        super(info);
    }
}

//0異常
class ZeroException extends Exception{
    ZeroException(){}

    ZeroException(String message){
        super(message);
    }
}


public class ExceptionDemo5 {
    public static void main(String[] args) {
        try{
        getArea(0);
        }catch(FuShuException e){ //多異常豁生,就多catch兔毒,范圍越大的往后寫
            e.printStackTrace();
        }catch(ZeroException e){
             e.printStackTrace();
        }
    }
    public static int getArea(int num) throws FuShuException,ZeroException{
        if(num < 0){
            throw new FuShuException("邊長是負(fù)數(shù)");
        }
        else if(num == 0){
             throw new ZeroException("邊長為0");
        }

        return (int)Math.pow(num,2);
    }
}

九、繼承異常

前提:子類重寫父類的方法

  • 父類的方法拋出了異常甸箱,子類重寫后育叁,異常:父類拋異常,子類可拋可不拋芍殖,但是豪嗽,如果子類拋,不能拋出比父類還大的異常
  • 父類的方法不拋異常,子類重寫后昵骤,子類不能拋出異常树碱。如果子類重寫的方法中,調(diào)用了一個(gè)拋異常的方法变秦,子類別無選擇成榜,只能try...catch處理異常

demo

package exceptions;

/*
 * 自定義異常
 * 1.父類方法拋異常,子類重寫后可拋可不拋蹦玫,若是拋赎婚,則要小于父類(前提是子類重寫了父類方法)
 * 2.父類方法不拋異常,子類也不能拋樱溉,若是子類調(diào)用的方法拋了異常挣输,子類只能try catch
 */

//A是父類異常類
class AException extends Exception{

}
//B繼承A
class BException extends AException{
    
}
//C和A是兄弟類
class CException extends Exception{
    
}

class Zi extends Fu{
    public void show() throws BException{}
}

class Fu{
    public void show() throws AException{}  
}

public class ExceptionDemo6 {
    public static void main(String[] args) throws AException{
        Fu f = new Zi();
       
          f.show();
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市福贞,隨后出現(xiàn)的幾起案子撩嚼,更是在濱河造成了極大的恐慌,老刑警劉巖挖帘,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件完丽,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡拇舀,警方通過查閱死者的電腦和手機(jī)逻族,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來骄崩,“玉大人聘鳞,你說我怎么就攤上這事∫鳎” “怎么了抠璃?”我有些...
    開封第一講書人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長脱惰。 經(jīng)常有香客問我鸡典,道長,這世上最難降的妖魔是什么枪芒? 我笑而不...
    開封第一講書人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任彻况,我火速辦了婚禮,結(jié)果婚禮上舅踪,老公的妹妹穿的比我還像新娘纽甘。我一直安慰自己,他們只是感情好抽碌,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開白布悍赢。 她就那樣靜靜地躺著决瞳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪左权。 梳的紋絲不亂的頭發(fā)上皮胡,一...
    開封第一講書人閱讀 49,730評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音赏迟,去河邊找鬼屡贺。 笑死,一個(gè)胖子當(dāng)著我的面吹牛锌杀,可吹牛的內(nèi)容都是我干的甩栈。 我是一名探鬼主播,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開眼糕再,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼量没!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起突想,我...
    開封第一講書人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤殴蹄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后猾担,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體饶套,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年垒探,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怠李。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡圾叼,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捺癞,到底是詐尸還是另有隱情夷蚊,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布髓介,位于F島的核電站惕鼓,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏唐础。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望姓建。 院中可真熱鬧惠昔,春花似錦、人聲如沸豹绪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至蝉衣,卻和暖如春括尸,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背病毡。 一陣腳步聲響...
    開封第一講書人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來泰國打工濒翻, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人剪验。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓肴焊,卻偏偏與公主長得像,于是被迫代替她去往敵國和親功戚。 傳聞我的和親對(duì)象是個(gè)殘疾皇子娶眷,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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

  • 通俗編程——白話JAVA異常機(jī)制 - 代碼之道,編程之法 - 博客頻道 - CSDN.NEThttp://blog...
    葡萄喃喃囈語閱讀 3,171評(píng)論 0 25
  • Java異常類型 所有異常類型都是Throwable的子類啸臀,Throwable把異常分成兩個(gè)不同分支的子類Erro...
    予別她閱讀 921評(píng)論 0 2
  • 一轧铁、多態(tài) 1. 概述 理解:多態(tài)可以理解為事物存在的多種體(表)現(xiàn)形態(tài)。例如:動(dòng)物中的貓和狗旦棉。貓這個(gè)對(duì)象對(duì)應(yīng)的是貓...
    陳凱冰閱讀 335評(píng)論 0 1
  • 今天下午飯都沒有吃飽就把飯給倒了绑洛,因?yàn)橄挛绯燥垥r(shí)間只有半小時(shí)救斑,而我們?cè)谒臉巧习啵程秒x我們又遠(yuǎn)真屯,走到食堂都5:10...
    掌心日記閱讀 392評(píng)論 0 0
  • 大偉滿足了若希對(duì)男人所有的幻想脸候。知情識(shí)趣,浪漫體貼绑蔫。明知他永遠(yuǎn)不缺女人运沦,還是愿意默默守候,奢望有天能感動(dòng)他配深。 這天...
    煙行閱讀 269評(píng)論 0 4