Java基礎(chǔ)-異常

什么是異常

異常是指阻止當(dāng)前方法或者作用域繼續(xù)執(zhí)行的問題潮改。異常對象(包括Exception和Error)都是Throwable的子類對象,都具有可拋性。不同的是凝果,Exception是JVM發(fā)出的異常提示,可以進行處理睦尽;Error是由操作系統(tǒng)發(fā)出的異常提示器净,一旦出現(xiàn)Error,必須修改源代碼骂删。

異常處理機制

在 Java 中掌动,異常處理機制有兩種,分別為拋出異常和捕獲異常宁玫。

拋出異常

當(dāng)一個方法出現(xiàn)錯誤引發(fā)異常時粗恢,方法創(chuàng)建異常對象并交付運行時系統(tǒng),異常對象中包含了異常類型和異常出現(xiàn)時的程序狀態(tài)等異常信息欧瘪。運行時系統(tǒng)負(fù)責(zé)尋找處置異常的代碼并執(zhí)行眷射。

捕獲異常

在方法拋出異常之后,運行時系統(tǒng)將轉(zhuǎn)為尋找合適的異常處理器(exception handler)。潛在的異常處理器是異常發(fā)生時依次存留在調(diào)用棧中的方法的集合妖碉。當(dāng)異常處理器所能處理的異常類型與方法拋出的異常類型相符時涌庭,即為合適 的異常處理器。運行時系統(tǒng)從發(fā)生異常的方法開始欧宜,依次回查調(diào)用棧中的方法坐榆,直至找到含有合適異常處理器的方法并執(zhí)行。當(dāng)運行時系統(tǒng)遍歷調(diào)用棧而未找到合適 的異常處理器冗茸,則運行時系統(tǒng)終止席镀。同時,意味著Java程序的終止夏漱。

異常的體系介紹


(圖片來自度娘)

Java作為一門面向?qū)ο蟮恼Z言豪诲,異常也被當(dāng)做對象來處理。
Throwable 類是所有異常類的根類挂绰,它有兩個子類 Error 類和 Exception屎篱。
Error 類是所有 error 類型的父類,子類有 VirtualMachineError 和 IOError葵蒂。
Exception 類是所有 exception 類型的父類交播,子類大致分為:RuntimeException(NullPointerException、IndexOutOfBoundsException刹勃、IllegalArgumentException等) 和 非 RuntimeException(IOException堪侯、SQLException等)。

異常的處理方式

對于 Error 我們是沒有辦法處理的荔仁,只能改錯誤的代碼伍宦。而對于 Exception 我們可以使用 throws 關(guān)鍵詞拋出方法可能產(chǎn)生的異常,然后在調(diào)用方法時使用 try-catch 語句捕獲拋出的異常并進行相應(yīng)的處理乏梁。

例1:

我們先運行如下代碼:

public class Main {

    public static void main(String[] args) {
        div(4, 0);
        System.out.println("執(zhí)行可能存在問題的代碼");
    }

    public static int div(int a, int b) {
        return a / b;
    }
}

結(jié)果如下:

Exception in thread "main"   
java.lang.ArithmeticException: / by zero
    at com.xxx.Main.div(Main.java:11)
    at com.xxx.Main.main(Main.java:6)
    ...

在主線程發(fā)生除以0的算術(shù)異常次洼。而且在div方法下的語句沒有執(zhí)行,說明程序只是執(zhí)行到了發(fā)生異常的語句遇骑。
接下來我們來處理異常卖毁。將代碼按照下方代碼修改。

public class Main {

    public static void main(String[] args) {
        try {
            div(4,0);
            System.out.println("執(zhí)行可能存在問題的代碼");
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
            System.out.println("捕獲異常");
        }
    }

    public static int div(int a, int b) throws   
    ArithmeticException{
        if(b == 0) {
            throw new ArithmeticException("除數(shù)不能為0");
        }
        return a / b;
    }
}

我們在方法 div 后面聲明可能拋出算術(shù)異常:throws ArithmeticException落萎。然后產(chǎn)生錯誤的語句放入try-catch語句的try中亥啦,在catch將捕獲的異常及其追蹤輸出至標(biāo)準(zhǔn)錯誤流:e.printStackTrace()。再將通過 getMessage() 方法獲取的錯誤信息打印出來练链。為了讓用戶更好的了解異常翔脱,我們自己創(chuàng)建異常對象,并寫上異常信息媒鼓,然后拋出届吁。語句: throw new ArithmeticException("除數(shù)不能為0");
結(jié)果如下:

除數(shù)不能為0
java.lang.ArithmeticException: 除數(shù)不能為0
捕獲異常
    at com.xxx.Main.div(Main.java:18)
    at com.xxx.Main.main(Main.java:7)

我們發(fā)現(xiàn)異常信息使我們自定義的了错妖。

例2:

有時候我們需要自定義一些異常,參照下面的代碼就可以自己自定義一場了疚沐。這里try-catch語句變?yōu)榱藅ry-catch-finally語句暂氯。finally語句是無論是否發(fā)生異常,都將執(zhí)行的語句塊亮蛔。

public class Main {

    public static void main(String[] args) {

        Computer computer = new Computer();
        // 多個異常捕獲痴施,異常對象存在父子關(guān)系時,要求父類異常必須寫在下面
//        try {
//            computer.setStatus("進水");
//        } catch (EnterWaterException e) {
//            e.printStackTrace();
//        } catch (Exception e) {
//            e.printStackTrace();
//        }

        // 多個異扯耍可以合并在一個catch塊
        try {
            computer.setStatus("進水了");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            System.out.println("finally");
        }
    }
}
class Computer {

    private String status;

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) throws DownException, EnterWaterException {
        this.status = status;
        if (status.equals("進水了")) {
            throw new EnterWaterException("進水了晾剖,短路了");
        } else if (status.equals("摔了")) {
            throw new DownException("摔了,碎了");
        }
    }
}

class EnterWaterException extends RuntimeException{
    public EnterWaterException(String message) {
        super(message);
    }
}

class DownException extends RuntimeException{
    public DownException(String message) {
        super(message);
    }
}

使用異常需要注意的問題

1.runtime的異程菟裕可以不捕獲就可以過編譯。
2.多個異常捕獲沽损,異常對象存在父子關(guān)系時灯节,要求父類異常必須寫在下面。
3.多個異常如果沒有不一樣的操作可以合并在一個catch塊中绵估,參數(shù)用共同的父類炎疆。

更多的注意事項請參考Java中的異常處理中的“那些不好的習(xí)慣”。

常見異常

在Java中提供了一些異常用來描述經(jīng)常發(fā)生的錯誤国裳,對于這些異常形入,有的需要程序員進行捕獲處理或聲明拋出,有的是由Java虛擬機自動進行捕獲處理缝左。

RuntimeException子類:

1亿遂、 java.lang.ArrayIndexOutOfBoundsException 數(shù)組索引越界異常。當(dāng)對數(shù)組的索引值為負(fù)數(shù)或大于等于數(shù)組大小時拋出渺杉。
2蛇数、java.lang.ArithmeticException 算術(shù)條件異常。譬如:整數(shù)除零等是越。
3耳舅、java.lang.NullPointerException 空指針異常。當(dāng)應(yīng)用試圖在要求使用對象的地方使用了null時倚评,拋出該異常浦徊。譬如:調(diào)用null對象的實例方法、訪問null對象的屬性天梧、計算null對象的長度盔性、使用throw語句拋出null等等。
4腿倚、java.lang.ClassNotFoundException 找不到類異常纯出。當(dāng)應(yīng)用試圖根據(jù)字符串形式的類名構(gòu)造類蚯妇,而在遍歷CLASSPAH之后找不到對應(yīng)名稱的class文件時,拋出該異常暂筝。
5箩言、java.lang.NegativeArraySizeException 數(shù)組長度為負(fù)異常
6、java.lang.ArrayStoreException 數(shù)組中包含不兼容的值拋出的異常
7焕襟、java.lang.SecurityException 安全性異常
8陨收、java.lang.IllegalArgumentException 非法參數(shù)異常

IOException

1、IOException:操作輸入流和輸出流時可能出現(xiàn)的異常鸵赖。
2务漩、EOFException 文件已結(jié)束異常
3、FileNotFoundException 文件未找到異常

其他

1它褪、ClassCastException 類型轉(zhuǎn)換異常類
2饵骨、ArrayStoreException 數(shù)組中包含不兼容的值拋出的異常
3、SQLException 操作數(shù)據(jù)庫異常類
4茫打、NoSuchFieldException 字段未找到異常
5居触、NoSuchMethodException 方法未找到拋出的異常
6、NumberFormatException 字符串轉(zhuǎn)換為數(shù)字拋出的異常
7老赤、StringIndexOutOfBoundsException 字符串索引超出范圍拋出的異常
8轮洋、IllegalAccessException 不允許訪問某類異常
9、InstantiationException 當(dāng)應(yīng)用程序試圖使用Class類中的newInstance()方法創(chuàng)建一個類的實例抬旺,而指定的類對象無法被實例化時弊予,拋出該異常

參考博客:
http://blog.csdn.net/hguisu/article/details/6155636
http://www.jellythink.com/archives/1420

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市开财,隨后出現(xiàn)的幾起案子汉柒,更是在濱河造成了極大的恐慌,老刑警劉巖床未,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件竭翠,死亡現(xiàn)場離奇詭異,居然都是意外死亡薇搁,警方通過查閱死者的電腦和手機斋扰,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來啃洋,“玉大人传货,你說我怎么就攤上這事『曷Γ” “怎么了问裕?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長孵坚。 經(jīng)常有香客問我粮宛,道長窥淆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任巍杈,我火速辦了婚禮忧饭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘筷畦。我一直安慰自己词裤,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布鳖宾。 她就那樣靜靜地躺著吼砂,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鼎文。 梳的紋絲不亂的頭發(fā)上渔肩,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音拇惋,去河邊找鬼赖瞒。 笑死,一個胖子當(dāng)著我的面吹牛蚤假,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播吧兔,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼磷仰,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了境蔼?” 一聲冷哼從身側(cè)響起灶平,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎箍土,沒想到半個月后逢享,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡吴藻,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年瞒爬,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片沟堡。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡侧但,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出航罗,到底是詐尸還是另有隱情禀横,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布粥血,位于F島的核電站柏锄,受9級特大地震影響酿箭,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜趾娃,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一缭嫡、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧茫舶,春花似錦械巡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至疹启,卻和暖如春古程,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背喊崖。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工挣磨, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人荤懂。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓茁裙,卻偏偏與公主長得像,于是被迫代替她去往敵國和親节仿。 傳聞我的和親對象是個殘疾皇子晤锥,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,472評論 2 348

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