【JavaSE】異常機(jī)制

異常指程序運(yùn)行過程中出現(xiàn)的非正常現(xiàn)象冬三,例如用戶輸入錯誤匀油、除數(shù)為零、需要處理的 文件不存在勾笆、數(shù)組下標(biāo)越界等敌蚜。
所謂異常處理,就是指程序在出現(xiàn)問題時依然可以正確的執(zhí)行完窝爪。
Java 是采用面向?qū)ο蟮姆绞絹硖幚懋惓5某诔怠L幚磉^程:

  • 拋出異常:在執(zhí)行一個方法時,如果發(fā)生異常蒲每,則這個方法生成代表該異常的一個 對象纷跛,停止當(dāng)前執(zhí)行路徑,并把異常對象提交給 JRE邀杏。
  • 捕獲異常:JRE 得到該異常后贫奠,尋找相應(yīng)的代碼來處理該異常。JRE 在方法的調(diào)用 棧中查找,從生成異常的方法開始回溯叮阅,直到找到相應(yīng)的異常處理代碼為止刁品。

一、異常分類

Java 對異常進(jìn)行了分類浩姥,不同類型的異常分別用不同的 Java 類表示挑随,所有異常的根類 為 java.lang.Throwable,Throwable 下面又派生了兩個子類:Error 和 Exception勒叠。


Java 異常類層次結(jié)構(gòu)圖

1. Error

Error 是程序無法處理的錯誤兜挨,表示運(yùn)行應(yīng)用程序中較嚴(yán)重問題。大多數(shù)錯誤與代碼編 寫者執(zhí)行的操作無關(guān)眯分,而表示代碼運(yùn)行時 JVM(Java 虛擬機(jī))出現(xiàn)的問題拌汇。例如,Java 虛擬機(jī)運(yùn)行錯誤(Virtual MachineError)弊决,當(dāng) JVM 不再有繼續(xù)執(zhí)行操作所需的內(nèi)存資源時噪舀,將出現(xiàn) OutOfMemoryError。這些異常發(fā)生時飘诗,Java 虛擬機(jī)(JVM)一般會選擇線 程終止与倡。 Error 表明系統(tǒng) JVM 已經(jīng)處于不可恢復(fù)的崩潰狀態(tài)中。我們不需要管他昆稿。


java.lang包下的Error類

2. Exception

Exception 是程序本身能夠處理的異常纺座,如:空指針異常(NullPointerException)、數(shù) 組 下 標(biāo) 越 界 異 常 ( ArrayIndexOutOfBoundsException )溉潭、類 型 轉(zhuǎn) 換 異 常 (ClassCastException)净响、算術(shù)異常(ArithmeticException)等。Exception 類是所有異常類的父類喳瓣,其子類對應(yīng)了各種各樣可能出現(xiàn)的異常事件馋贤。
通常 Java 的異常可分為:

  1. RuntimeException 運(yùn)行時異常
  2. CheckedException 已檢查異常

3. RuntimeException

派生于 RuntimeException 的異常畏陕,如被 0 除掸掸、數(shù)組下標(biāo)越界、空指針等蹭秋,其產(chǎn)生比較頻繁,處理麻煩堤撵,如果顯式的聲明或捕獲將會對程序可讀性和運(yùn)行效率影響很大仁讨。 因此 由系統(tǒng)自動檢測并將它們交給缺省的異常處理程序(用戶可不必對其處理)。
這類異常通常是由編程錯誤導(dǎo)致的实昨,所以在編寫程序時洞豁,并不要求必須使用異常處理機(jī) 制來處理這類異常,經(jīng)常需要通過增加“邏輯處理來避免這些異常”。
常見的運(yùn)行時異常:

  1. ArithmeticException 異常:試圖除以 0
public class Test3 { 
  public static void main(String[ ] args) { 
    int b=0; 
    System.out.println(1/b); 
  } 
}
image.png
  1. NullPointerException 異常
public class Test4 { 
  public static void main(String[ ] args) {
    String str=null; 
    System.out.println(str.charAt(0)); 
  } 
}
NullPointerException 異常
  1. ClassCastException 異常
class Animal{ 
}
class Dog extends Animal{
 }
class Cat extends Animal{ 
}
public class Test5 { 
  public static void main(String[ ] args) { 
    Animal a=new Dog(); 
    Cat c=(Cat)a; 
  } 
}
ClassCastException 異常
  1. ArrayIndexOutOfBoundsException 異常
public class Test6 { 
  public static void main(String[ ] args) {
    int[ ] arr = new int[5]; 
    System.out.println(arr[5]); 
  } 
}
ArrayIndexOutOfBoundsException 異常
  1. NumberFormatException 異常
public class Test7 { 
  public static void main(String[ ] args) {
    String str = "1234abcf"; 
    System.out.println(Integer.parseInt(str)); 
  } 
}
NumberFormatException 異常

4. CheckedException

所有不是 RuntimeException 的異常丈挟,統(tǒng)稱為 Checked Exception刁卜,又被稱為“已檢 查異常”曙咽,如 IOException蛔趴、SQLException 等以及用戶自定義的 Exception 異常。 這類 異常在編譯時就必須做出處理例朱,否則無法通過編譯孝情。
異常的處理方式有兩種:使用“try/catch”捕獲異常、使用“throws” 聲明異常洒嗤。

二箫荡、異常捕獲

捕獲異常是通過 3 個關(guān)鍵詞來實(shí)現(xiàn)的:try-catch-finally。用 try 來執(zhí)行一段程序渔隶,如 果出現(xiàn)異常羔挡,系統(tǒng)拋出一個異常,可以通過它的類型來捕捉(catch)并處理它间唉,最后一步 是通過 finally 語句為異常處理提供一個統(tǒng)一的出口绞灼,finally 所指定的代碼都要被執(zhí)行 (catch 語句可有多條;finally 語句最多只能有一條终吼,根據(jù)自己的需要可有可無)镀赌。

try{
  可能出現(xiàn)異常的代碼
}catch(異常類型 變量名){
  出現(xiàn)異常時執(zhí)行的代碼
}....catch(異常類型 變量名){
  出現(xiàn)異常時執(zhí)行的代碼
}finally{
  最后要執(zhí)行的代碼
}

注意:

  1. 一個try后可以有1~n個catch
  2. catch是從上到下依次判斷執(zhí)行,try中沒有出現(xiàn)異常际跪,不會執(zhí)行catch判斷捕獲商佛。一旦出現(xiàn)異常,try中后面的代碼不會執(zhí)行
  3. 如果catch中捕獲的異常類型比較大姆打,應(yīng)放在最后
  4. finally:當(dāng)前try ... catch的結(jié)構(gòu)執(zhí)行結(jié)束后良姆,會執(zhí)行finally中的代碼(一般為釋放資源的代碼)
    例:
public class Test8 { 
  public static void main(String[ ] args) { 
    FileReader reader = null; 
    try {
      reader = new FileReader("d:/a.txt"); 
      char c = (char) reader.read(); 
      char c2 = (char) reader.read(); 
      System.out.println("" + c + c2); 
    } catch (FileNotFoundException e) { 
      e.printStackTrace(); 
    } catch (IOException e) { 
      e.printStackTrace(); 
    } finally {
      try {
         if (reader != null) { 
           reader.close(); 
         } 
      } catch (Exception e) {
           e.printStackTrace(); 
      } 
    } 
  } 
}

三、聲明異常

當(dāng) CheckedException 產(chǎn)生時幔戏,不一定立刻處理它玛追,可以再把異常 throws 出去。
在方法中使用 try-catch-finally 是由這個方法來處理異常闲延。但是在一些情況下痊剖,當(dāng)前方法并不需要處理發(fā)生的異常,而是向上傳遞給調(diào)用它的方法處理垒玲。
如果一個方法中可能產(chǎn)生某種異常陆馁,但是并不能確定如何處理這種異常,則應(yīng)根據(jù)異常規(guī)范在方法的首部聲明該方法可能拋出的異常合愈。
如果一個方法拋出多個已檢查異常叮贩,就必須在方法的首部列出所有的異常击狮,之間以逗號隔開。

public static void readFile(String fileName) throws FileNotFoundException, IOException {
        FileReader in = new FileReader(fileName);
        int tem = 0;
        try {
            tem = in.read();
            while (tem != -1) {
                System.out.print((char) tem);
                tem = in.read();
            }
        } finally {
            if (in != null) {
                in.close();
            }
        }
    }

四益老、try-with-resource 自動關(guān)閉 Closable 接口的資源

public class Test8 {
    public static void main(String[] args) {
        try (FileReader reader = new FileReader("d:/a.txt");) { //try-with-resource
            char c = (char) reader.read();
            char c2 = (char) reader.read();
            System.out.println("" + c + c2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

五彪蓬、自定義異常

  • 在程序中,可能會遇到 JDK 提供的任何標(biāo)準(zhǔn)異常類都無法充分描述清楚我們想要 表達(dá)的問題捺萌,這種情況下可以創(chuàng)建自己的異常類档冬,即自定義異常類。
  • 自定義異常類只需從 Exception 類或者它的子類派生一個子類即可互婿。
  • 自定義異常類如果繼承 Exception 類捣郊,則為受檢查異常,必須對其進(jìn)行處理慈参;如果不想處理呛牲,可以讓自定義異常類繼承運(yùn)行時異常 RuntimeException 類。
  • 習(xí)慣上驮配,自定義異常類應(yīng)該包含 2 個構(gòu)造器:一個是默認(rèn)的構(gòu)造器娘扩,另一個是帶 有詳細(xì)信息的構(gòu)造器。
class IllegalAgeException extends Exception {
    public IllegalAgeException() {
    }//帶有詳細(xì)信息的構(gòu)造器壮锻,信息存儲在 message 中 

    public IllegalAgeException(String message) {
        super(message);
    }
}

自定義異常的使用:

public void setAge(int age) throws IllegalAgeException { 
  if (age < 0) { 
    throw new IllegalAgeException("人的年齡不應(yīng)該為負(fù)數(shù)"); 
  }
  this.age = age; 
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末琐旁,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子猜绣,更是在濱河造成了極大的恐慌灰殴,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件掰邢,死亡現(xiàn)場離奇詭異牺陶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)辣之,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門掰伸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人怀估,你說我怎么就攤上這事狮鸭。” “怎么了多搀?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵歧蕉,是天一觀的道長。 經(jīng)常有香客問我康铭,道長廊谓,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任麻削,我火速辦了婚禮蒸痹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘呛哟。我一直安慰自己叠荠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布扫责。 她就那樣靜靜地躺著榛鼎,像睡著了一般。 火紅的嫁衣襯著肌膚如雪鳖孤。 梳的紋絲不亂的頭發(fā)上者娱,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機(jī)與錄音苏揣,去河邊找鬼黄鳍。 笑死,一個胖子當(dāng)著我的面吹牛平匈,可吹牛的內(nèi)容都是我干的框沟。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼增炭,長吁一口氣:“原來是場噩夢啊……” “哼忍燥!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起隙姿,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤梅垄,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后输玷,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體队丝,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡捧杉,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年岂却,在試婚紗的時候發(fā)現(xiàn)自己被綠了驱证。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片羊苟。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡艰匙,死狀恐怖搬设,靈堂內(nèi)的尸體忽然破棺而出问麸,到底是詐尸還是另有隱情伙判,我是刑警寧澤尽狠,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布衔憨,位于F島的核電站,受9級特大地震影響袄膏,放射性物質(zhì)發(fā)生泄漏践图。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一沉馆、第九天 我趴在偏房一處隱蔽的房頂上張望码党。 院中可真熱鬧德崭,春花似錦、人聲如沸揖盘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽兽狭。三九已至憾股,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間箕慧,已是汗流浹背服球。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留颠焦,地道東北人斩熊。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像蒸健,于是被迫代替她去往敵國和親座享。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

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

  • 什么是異常似忧? 異常本質(zhì)上是程序上的錯誤渣叛,錯誤在我們編寫程序的過程中會經(jīng)常發(fā)生,包括編譯期間和運(yùn)行期間的錯誤盯捌。 編譯...
    若兮緣閱讀 3,374評論 0 11
  • 目錄介紹 1.什么是異常 2.異常2.1 異常的概述和分類【了解】2.2 JVM默認(rèn)是如何處理異常的【理解】2.3...
    楊充211閱讀 317評論 0 1
  • 2.JAVA異常 異常指不期而至的各種狀況淳衙,如:文件找不到、網(wǎng)絡(luò)連接失敗饺著、非法參數(shù)等箫攀。異常是一個事件,它發(fā)生在程...
    青城樓主閱讀 561評論 0 0
  • 通俗編程——白話JAVA異常機(jī)制 - 代碼之道幼衰,編程之法 - 博客頻道 - CSDN.NEThttp://blog...
    葡萄喃喃囈語閱讀 3,181評論 0 25
  • 概念介紹 異常是發(fā)生在程序執(zhí)行過程中阻礙程序正常執(zhí)行的錯誤事件靴跛,當(dāng)一個程序出現(xiàn)錯誤時,可能的情況有如下3種: 語法...
    niaoge2016閱讀 5,187評論 2 20