1 異常概述與異常體系結(jié)構(gòu)
1.1?異常定義
??? (1)在使用計(jì)算機(jī)語(yǔ)言進(jìn)行項(xiàng)目開(kāi)發(fā)的過(guò)程中,即使程序員把代碼寫(xiě)得盡善盡美,在系統(tǒng)的運(yùn)行過(guò)程中仍然會(huì)遇到一些問(wèn)題,因?yàn)楹芏鄦?wèn)題不是靠代碼能夠避免的,比如:客戶(hù)輸入數(shù)據(jù)的格式,讀取文件是否存在,網(wǎng)絡(luò)是否始終保持通暢等等。
??? (2)在 Java 語(yǔ)言中,將程序執(zhí)行中發(fā)生的不正常情況稱(chēng)為“異?!?。 ( 開(kāi)發(fā)過(guò)程中的語(yǔ)法錯(cuò)誤和邏輯錯(cuò)誤不是異常 )
1.2?異常事件分類(lèi)
Error |
Java 虛擬機(jī)無(wú)法解決的嚴(yán)重問(wèn)題,一般不編寫(xiě)針對(duì)性的代碼進(jìn)行處理。 Error 類(lèi)描述內(nèi)部錯(cuò)誤,由系統(tǒng)保留,程序不能拋出這個(gè)類(lèi)型的對(duì)象,Error 類(lèi)的對(duì)象不可捕捉,不可恢復(fù),出錯(cuò)時(shí)由系統(tǒng)通知用戶(hù)并終止程序。 如:JVM 系統(tǒng)內(nèi)部錯(cuò)誤、資源耗盡等嚴(yán)重情況。比如:StackOverflowError 和 OOM。 |
Exception |
其它因編程錯(cuò)誤或偶然的外在因素導(dǎo)致的一般性問(wèn)題,可以使用針對(duì)性的代碼進(jìn)行處理。 Exception 類(lèi)供應(yīng)用程序使用,所有的 Java 異常類(lèi)都是系統(tǒng)類(lèi)庫(kù)中 Exception 類(lèi)的子類(lèi)。 如:空指針訪問(wèn)、試圖讀取不存在的文件、網(wǎng)絡(luò)連接中斷、數(shù)組角標(biāo)越界 |
?1.3?異常解決方法
? ? ?(1)遇到錯(cuò)誤就終止程序的運(yùn)行。
??? (2)由程序員在編寫(xiě)程序時(shí),就考慮到錯(cuò)誤的檢測(cè)、錯(cuò)誤消息的提示、以及錯(cuò)誤的處理。
1.4 Exception 分類(lèi)
運(yùn)行時(shí)異常 (非受檢異常) |
指編譯器不要求強(qiáng)制處置的異常。一般是指編程時(shí)的邏輯錯(cuò)誤,是程序員應(yīng)該積極避免其出現(xiàn)的異常。 java.lang.RuntimeException 類(lèi)及它的子類(lèi)都是運(yùn)行時(shí)異常。 對(duì)于運(yùn)行時(shí)異常,可以不作處理,因?yàn)檫@類(lèi)異常很普遍,若全處理可能會(huì)對(duì)程序的可讀性和運(yùn)行效率產(chǎn)生影響。 |
編譯時(shí)異常 (受檢異常) |
指編譯器要求必須處置的異常。即程序在運(yùn)行時(shí)由于外界因素造成的一般性異常。編譯器要求 Java 程序必須捕獲或聲明所有編譯時(shí)異常。 對(duì)于這類(lèi)異常,如果程序不處理,可能會(huì)帶來(lái)意想不到的結(jié)果。 |
1.5?異常繼承結(jié)構(gòu)
1.6?常見(jiàn)異常
??? (1)java.lang.RuntimeException:運(yùn)行時(shí)異常
ClassCastException: |
類(lèi)型轉(zhuǎn)換異常 |
ArrayIndexOutOfBoundsException: |
數(shù)組下標(biāo)越界異常 |
NullPointerException: |
空指針異常 |
ArithmeticException: |
算術(shù)異常 |
NumberFormatException: |
數(shù)字格式異常 |
InputMismatchException: |
輸入不匹配異常 |
??? (2) java.io.IOExeption: IO 異常
FileNotFoundException: |
文件未找到異常 |
EOFException: |
end of file ,文件到達(dá)結(jié)尾異常 |
??? (3) java.lang.ClassNotFoundException:類(lèi)未找到異常
??? (4) java.lang.InterruptedException:中斷異常
??? (5) java.sql.SQLException:SQL 異常
2. 異常處理機(jī)制一:try-catch-finally
2.1?問(wèn)題引入
??? (1)在編寫(xiě)程序時(shí),經(jīng)常要在可能出現(xiàn)錯(cuò)誤的地方加上檢測(cè)的代碼,如進(jìn)行 x/y 運(yùn)算時(shí),要檢測(cè)分母是否為 0,數(shù)據(jù)為空,輸入的不是數(shù)據(jù)而是字符等。過(guò)多的 if-else 分支會(huì)導(dǎo)致程序的代碼加長(zhǎng)、臃腫,可讀性差。因此 Java 提供了異常處理機(jī)制。
────────────────────────────────────────────────────────────
2.2?Java 異常處理機(jī)制
??? (1)可以方便在程序中監(jiān)視可能發(fā)生異常的代碼塊,并將所有異常處理代碼集中放置在程序某處,使完成正常功能的程序代碼與進(jìn)行異常處理的程序代碼分開(kāi)。使得降低編程人員的工作量,增強(qiáng)了異常處理的靈活性,使得程序的可讀性和可維護(hù)性大為提高,簡(jiǎn)潔、優(yōu)雅、并易于維護(hù)
??? (2)在 Java 的異常處理機(jī)制中,引入一些用來(lái)描述和處理異常的類(lèi),每個(gè)異常類(lèi)反映一類(lèi)運(yùn)行錯(cuò)誤,在類(lèi)的定義中包含了該類(lèi)異常的信息和對(duì)異常進(jìn)行處理的方法。當(dāng)程序運(yùn)行的過(guò)程中發(fā)生某個(gè)異?,F(xiàn)象時(shí),系統(tǒng)就產(chǎn)生一個(gè)與之相應(yīng)的異常類(lèi)對(duì)象,并交與系統(tǒng)中的相應(yīng)機(jī)制進(jìn)行處理,以避免系統(tǒng)崩潰或其他對(duì)系統(tǒng)有害的結(jié)果發(fā)生,保證了程序運(yùn)行的安全性
────────────────────────────────────────────────────────────
2.3 異常對(duì)象的生成方式
??? (1)虛擬機(jī)自動(dòng)生成:程序運(yùn)行過(guò)程中,虛擬機(jī)檢測(cè)到程序發(fā)生了問(wèn)題,如果在當(dāng)前代碼中沒(méi)有找到相應(yīng)的處理程序,就會(huì)在后臺(tái)自動(dòng)創(chuàng)建一個(gè)對(duì)應(yīng)異常類(lèi)的實(shí)例對(duì)象并拋出(自動(dòng)拋出)
??? (2)開(kāi)發(fā)人員手動(dòng)創(chuàng)建:Exception exception = new ClassCastException(); 創(chuàng)建好的異常對(duì)象不拋出對(duì)程序沒(méi)有任何影響,和創(chuàng)建一個(gè)普通對(duì)象一樣。
────────────────────────────────────────────────────────────
2.4 異常處理:抓拋模型
拋 |
Java 程序的執(zhí)行過(guò)程中如果出現(xiàn)異常,會(huì)生成一個(gè)異常類(lèi)對(duì)象,該異常對(duì)象將被提交給 Java 運(yùn)行時(shí)系統(tǒng),這個(gè)過(guò)程稱(chēng)為拋出( throw )異常 |
抓 |
捕捉異常—>程序流程的跳轉(zhuǎn)—>異常處理語(yǔ)句塊的定義異常的處理方式 |
────────────────────────────────────────────────────────────
2.5?捕捉異常
??? (1)如果一個(gè)方法內(nèi)拋出異常,該異常對(duì)象會(huì)被拋給調(diào)用者方法中處理。如果異常沒(méi)有在調(diào)用者方法中處理,它繼續(xù)被拋給這個(gè)調(diào)用方法的上層方法。這個(gè)過(guò)程將一直繼續(xù)下去,直到異常被處理。這一過(guò)程稱(chēng)為捕獲(catch)異常。如果一個(gè)異?;氐?main() 方法,并且 main() 也不處理,則程序運(yùn)行終止。
??? (2)程序員通常只能處理 Exception,而對(duì) Error 無(wú)能為力。
??? (3)捕獲異常的有關(guān)信息方法:
異常對(duì)象.getMessage() |
獲取異常信息,返回字符串 |
異常對(duì)象.printStackTrace() |
獲取異常類(lèi)名和異常信息,以及異常出現(xiàn)在程序中的位置。返回值 void。 |
────────────────────────────────────────────────────────────
2.6?try—catch—finally 的語(yǔ)法格式使用
|
────────────────────────────────────────────────────────────
2.7?try—catch—finally 的使用
|
捕獲異常的第一步是用 try{…} 語(yǔ)句塊選定捕獲異常的范圍,將可能出現(xiàn)異常的代碼放在 try 語(yǔ)句塊中。 |
catch(可選) |
在 catch 語(yǔ)句塊中是對(duì)異常對(duì)象進(jìn)行處理的代碼。每個(gè) try 語(yǔ)句塊可以伴隨一個(gè)或多個(gè) catch 語(yǔ)句,用于處理可能產(chǎn)生的不同類(lèi)型的異常對(duì)象。如果被捕捉的各類(lèi)異常之間沒(méi)有父子關(guān)系,各類(lèi)的順序無(wú)關(guān)緊要,如果有父子關(guān)系,應(yīng)該將子類(lèi)的 catch 塊放置在父類(lèi)的 catch 塊之前。 |
finally(可選) |
捕獲異常的最后一步是通過(guò) finally 語(yǔ)句為異常處理提供一個(gè)統(tǒng)一的出口,使得在控制流轉(zhuǎn)到程序的其它部分以前,能夠?qū)Τ绦虻臓顟B(tài)作統(tǒng)一的管理。不論在 try 代碼塊中是否發(fā)生了異常事件,catch 語(yǔ)句是否執(zhí)行,catch 語(yǔ)句是否有異常,catch 語(yǔ)句中是否有 return,finally 塊中的語(yǔ)句都會(huì)被執(zhí)行。 |
try—catch—finally 可以使代碼可以在編譯時(shí)通過(guò),但運(yùn)行時(shí)仍可能會(huì)出錯(cuò) 在 try 中聲明的變量,在 try 結(jié)構(gòu)外無(wú)法再使用,可以在外部聲明賦值,try 內(nèi)部使用 一旦出現(xiàn)異常,try 內(nèi)異常代碼后的代碼將不會(huì)執(zhí)行,直接執(zhí)行到相應(yīng)的 catch 異常處理中 |
3. 異常處理機(jī)制二:throws
3.1?throws + 異常類(lèi)型
??? (1)throws + 異常類(lèi)型寫(xiě)在方法的聲明處,指明方法執(zhí)行時(shí)可能拋出的異常類(lèi)型,一旦方法執(zhí)行時(shí)出現(xiàn)異常,就會(huì)在異常代碼處生成一個(gè)異常類(lèi)的對(duì)象,此對(duì)象滿(mǎn)足 throws 后面的類(lèi)型時(shí),就會(huì)被拋出,異常后的代碼不會(huì)再執(zhí)行。
────────────────────────────────────────────────────────────
3.2?throws 和 try—catch—finally 的區(qū)別
try - catch - finally: |
真正的異常處理 |
throws: |
將異常拋給了方法的調(diào)用者 |
────────────────────────────────────────────────────────────
3.3?開(kāi)發(fā)中如何選擇使用 try-catch-finally 還是使用 throws?
??? (1)如果父類(lèi)中被重寫(xiě)的方法沒(méi)有 throws 方式處理異常,則子類(lèi)重寫(xiě)的方法也不能使用 throws,意味著如果子類(lèi)重寫(xiě)的方法中有異常,必須使用 try-catch-finally 方式處理。
??? (2)執(zhí)行的方法 a 中,先后又調(diào)用了另外的幾個(gè)方法,這幾個(gè)方法是遞進(jìn)關(guān)系執(zhí)行的。我們建議這幾個(gè)方法使用 throws 的方式進(jìn)行處理。而執(zhí)行的方法 a 可以考慮使用 try-catch-finally 方式進(jìn)行處理。
────────────────────────────────────────────────────────────
3.4?重寫(xiě)方法聲明拋出異常的原則
??? (1)重寫(xiě)方法不能拋出比被重寫(xiě)方法范圍更大的異常類(lèi)型。在多態(tài)的情況下, 對(duì) methodA() 方法的調(diào)用-異常的捕獲按父類(lèi)聲明的異常處理。
4 手動(dòng)拋出異常:throw
4.1?異常對(duì)象的產(chǎn)生
??? (1)Java 異常類(lèi)對(duì)象除在程序執(zhí)行過(guò)程中出現(xiàn)異常時(shí)由系統(tǒng)自動(dòng)生成并拋出,也可根據(jù)需要人工創(chuàng)建異常對(duì)象并拋出(throw)。
??? (2)格式:throw 異常類(lèi)型
??? (3)使用場(chǎng)景:需要自定義規(guī)則的時(shí)候拋出不符合規(guī)則的異常
??? (4)要求:可以?huà)伋龅漠惓1仨毷?Throwable 或其子類(lèi)的實(shí)例。
首先手動(dòng)創(chuàng)建異常類(lèi)對(duì)象,然后通過(guò) throw 語(yǔ)句實(shí)現(xiàn)拋出操作(提交給 Java 運(yùn)行環(huán)境)
|
5 自定義異常類(lèi)
5.1?自定義異常類(lèi)引入
??? (1)如果預(yù)計(jì)程序可能產(chǎn)生一個(gè)特定的異常問(wèn)題,該問(wèn)題無(wú)法用系統(tǒng)定義的異常情況來(lái)描述。此時(shí)根據(jù)程序的特殊邏輯,在用戶(hù)程序中自定義一個(gè)異常情況類(lèi)和異常對(duì)象,主要用來(lái)處理用戶(hù)程序中特定的邏輯運(yùn)行錯(cuò)誤。
────────────────────────────────────────────────────────────
5.2?自定義異常類(lèi)作用
??? (1)用來(lái)處理程序中可能產(chǎn)生的特殊邏輯錯(cuò)誤。能夠被系統(tǒng)即使識(shí)別和處理而不擴(kuò)散產(chǎn)生更大的影響,使用戶(hù)程序具有更好的容錯(cuò)性,使系統(tǒng)更加安全穩(wěn)定。
────────────────────────────────────────────────────────────
5.3?自定義異常類(lèi)要求
??? (1)聲明一個(gè)新的異常類(lèi),作為 Exception 類(lèi)或其他某個(gè)已經(jīng)存在的系統(tǒng)異常類(lèi)或其他用戶(hù)異常類(lèi)的子類(lèi)。
??? (2)定義全局變量 serialVersionUID : 唯一標(biāo)識(shí)一個(gè)異常類(lèi)。
??? (3)為新的異常類(lèi)定義屬性和方法,或重載父類(lèi)的屬性和方法,使這些屬性和方法能夠體現(xiàn)該類(lèi)所對(duì)應(yīng)的錯(cuò)誤信息
|
|
6 異常處理總結(jié)
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-477107.html
文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-477107.html
到了這里,關(guān)于Java 異常處理機(jī)制(全)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!