Java中的異常Exception詳細(xì)解析
一、基本介紹
基本概念
Java語(yǔ)言中,將程序執(zhí)行中發(fā)生的不正常情況稱(chēng)為“ 異常 ”。(開(kāi)發(fā)過(guò)程中的語(yǔ)法錯(cuò)誤和邏輯錯(cuò)誤不是異常)
執(zhí)行過(guò)程中所發(fā)生的異常事件可分為兩大類(lèi)
1.Error(錯(cuò)誤):Java虛擬機(jī)無(wú)法解決的嚴(yán)重問(wèn)題。如:JVM系統(tǒng)內(nèi)部錯(cuò)誤、資源耗盡等嚴(yán)重情況。比如:StackOverflowError[棧溢出]和OOM(out of memory),Error是嚴(yán)重錯(cuò)誤,程序會(huì)崩潰
2.Exception:其它因編譯錯(cuò)誤和偶然的外在因素導(dǎo)致的一般性問(wèn)題,可以使用針對(duì)性的代碼進(jìn)行處理。例如空指針訪問(wèn),試圖讀取不存在的文件,網(wǎng)絡(luò)連接中斷等等,Exception分為兩大類(lèi):運(yùn)行時(shí)異常[程序運(yùn)行時(shí)發(fā)生的異常]和編譯時(shí)異常[編程時(shí)編譯器檢查出的異常]
異常類(lèi)層次結(jié)構(gòu)圖
異常體系圖小結(jié):
1.異常分為兩大類(lèi),運(yùn)行時(shí)異常和編譯時(shí)異常
2.運(yùn)行時(shí)異常,編譯器檢查不出來(lái)。一般是指編程時(shí)的邏輯錯(cuò)誤,是程序員應(yīng)該避免其出現(xiàn)的異常。java.lang.RuntimeException類(lèi)及它的子類(lèi)都是運(yùn)行時(shí)異常
3.對(duì)于運(yùn)行時(shí)異??梢圆蛔鎏幚恚?yàn)檫@類(lèi)異常很普遍,若全處理可能會(huì)對(duì)程序的可讀性和運(yùn)行效率產(chǎn)生影響
4.編譯時(shí)異常是編譯器要求必須處置的異常
常見(jiàn)的運(yùn)行時(shí)異常
1. NullPointerException 空指針異常
當(dāng)應(yīng)用程序試圖在需要對(duì)象的地方使用null時(shí),會(huì)拋出此異常
2. ArithmeticException 數(shù)學(xué)運(yùn)算異常
當(dāng)出現(xiàn)異常的運(yùn)算條件時(shí),會(huì)拋出此異常
3. ArrayIndexOutOfBoundsException 數(shù)組下標(biāo)越界異常
用非法索引訪問(wèn)數(shù)組時(shí)拋出的異常。如果索引為負(fù)或大于等于數(shù)組大小,則該索引為非法索引
4. ClassCastException 類(lèi)型轉(zhuǎn)換異常
當(dāng)試圖將對(duì)象強(qiáng)制轉(zhuǎn)換為不是實(shí)例的子類(lèi)時(shí),會(huì)拋出此異常
5.NumberFormatException 數(shù)字格式不正確異常
當(dāng)應(yīng)用程序試圖將字符串轉(zhuǎn)換成一種數(shù)值類(lèi)型,但該字符串不能轉(zhuǎn)換為適當(dāng)格式,會(huì)拋出此異常—>使用異常我們可以確保輸入是滿足條件數(shù)字
二、異常處理
基本介紹
異常處理就是當(dāng)異常發(fā)生時(shí),對(duì)異常處理的方式
異常處理的方式
1. try—catch—finally :程序員在代碼中捕獲發(fā)生的異常,自行處理
2. throws :將發(fā)生的異常拋出,交給調(diào)用者(方法)來(lái)處理,最頂級(jí)的處理者就是JVM
三、try-catch異常處理
1.Java提供try和catch塊來(lái)處理異常。try塊用于包含可能出錯(cuò)的代碼。catch塊用于處理try塊中發(fā)生的異常??梢愿鶕?jù)需要在程序中有多個(gè)try...catch塊
2.基本語(yǔ)法
try{ //可疑代碼 //將異常生成對(duì)應(yīng)的異常對(duì)象,傳遞給catch塊 }catch{ //對(duì)異常的處理 } //如果沒(méi)有finally,語(yǔ)法也可以通過(guò)
3. try-catch方式處理異常注意事項(xiàng)
①如果異常發(fā)生了,則異常發(fā)生后面的代碼不會(huì)執(zhí)行,直接進(jìn)入到catch塊
②如果異常沒(méi)有發(fā)生,則順序執(zhí)行try的代碼塊,不會(huì)進(jìn)入到catch
③如果希望不管是否發(fā)生異常,都執(zhí)行某段代碼(比如關(guān)閉連接,釋放資源等)則使用代碼 -finally{ }
try{ //可疑代碼 }catch(異常){ //.... }finally{ //釋放資源等.. }
4.可以有多個(gè)catch語(yǔ)句捕獲不同的異常(進(jìn)行不同的業(yè)務(wù)處理),要求子類(lèi)異常寫(xiě)在前面,父類(lèi)異常寫(xiě)在后面,比如(NullPointerException在前,Exception在后),如果發(fā)生異常,只會(huì)匹配一個(gè)catch
5.可以進(jìn)行try-finally配合使用,這種用法相當(dāng)于沒(méi)有捕獲異常,依次程序會(huì)直接崩掉/退出。應(yīng)用場(chǎng)景就是執(zhí)行一段代碼,不管是否發(fā)生異常,都必須執(zhí)行某個(gè)業(yè)務(wù)邏輯
try-catch-finally執(zhí)行順序小結(jié)
1.如果沒(méi)有出現(xiàn)異常,則執(zhí)行try塊中所有語(yǔ)句,不執(zhí)行catch塊中語(yǔ)句,如果有finally,最后還需要執(zhí)行finally里面的語(yǔ)句
2.如果出現(xiàn)異常,則try塊中異常發(fā)生后,try塊剩下的語(yǔ)句不會(huì)再執(zhí)行。將執(zhí)行catch塊中的語(yǔ)句,如果有finally,最后還需要執(zhí)行finally里的語(yǔ)句
public class TryCatchDetail { public static void main(String[] args) { //快捷鍵ctrl + alt + t //解讀 //1.如果發(fā)生異常,則異常后面的代碼塊不會(huì)執(zhí)行,直接進(jìn)入到catch塊 //2.如果異常沒(méi)有發(fā)生,則順序執(zhí)行try的代碼塊,不會(huì)進(jìn)入到catch //3.如果希望不管是否發(fā)生異常,都執(zhí)行某段代碼塊(比如關(guān)閉連接,釋放資源等)則使用代碼— finally try { String str = "123"; int a = Integer.parseInt(str); System.out.println("數(shù)字:" + a); } catch (NumberFormatException e) { System.out.println("異常信息=" + e.getMessage()); }finally{ System.out.println("finally代碼塊被執(zhí)行..."); } System.out.println("程序繼續(xù)執(zhí)行..."); } } public class TryCatchDetail02 { public static void main(String[] args) { //解讀 //1.如果try代碼塊可能有多個(gè)異常 //2.可以使用多個(gè)catch分別捕獲不同的異常,相應(yīng)處理 //3.要求子類(lèi)異常寫(xiě)在前面,父類(lèi)異常寫(xiě)在后面 try { Person person = new Person(); person = null; System.out.println(person.getName());//NullPointerException int n1 = 10; int n2 = 0; int res = n1 / n2;//ArithmeticException }catch (NullPointerException e) { System.out.println("空指針異常=" + e.getMessage()); }catch(ArithmeticException e) { System.out.println("算數(shù)異常=" + e.getMessage()); }catch (Exception e) { System.out.println("異常信息=" + e.getMessage()); }finally { } } } class Person { private String name; public String getName() { return name; } } public class TryCatchDetail03 { public static void main(String[] args) { /* 可以進(jìn)行try-finally配合使用,這種用法相當(dāng)于沒(méi)有捕獲異常,因此程序會(huì)直接崩掉/退出。 應(yīng)用場(chǎng)景就是執(zhí)行一段代碼,不管是否發(fā)生異常,都必須執(zhí)行某個(gè)業(yè)務(wù)邏輯 */ try{ int n1 = 10; int n2 = 0; System.out.println(n1 / n2); }finally { System.out.println("執(zhí)行了finally..."); } System.out.println("程序繼續(xù)執(zhí)行..."); } }
四、thorws異常處理
基本介紹
1.如果一個(gè)方法中的語(yǔ)句執(zhí)行時(shí)可能生成某種異常,但是并不能確定如何處理這種異常,則此方法應(yīng)顯示地聲明拋出異常,表明該方法將不對(duì)這些異常進(jìn)行處理,而由該方法的調(diào)用者負(fù)責(zé)處理
2.在方法生命中用throws語(yǔ)句可以聲明拋出異常的列表,thros后面的異常類(lèi)型可以是方法中產(chǎn)生的異常類(lèi)型,也可以是它的父類(lèi)
注意事項(xiàng)和使用細(xì)節(jié)
1.對(duì)于編譯異常,程序中必須處理,比如try-catch或者throws
2.對(duì)于運(yùn)行時(shí)異常,程序中如果沒(méi)有處理,默認(rèn)就是throws的方式處理
3.子類(lèi)重寫(xiě)父類(lèi)的方法時(shí),對(duì)拋出異常的規(guī)定:子類(lèi)重寫(xiě)的方法,所拋出的異常類(lèi)型要么和父類(lèi)拋出的異常一致,要么為父類(lèi)拋出的異常的子類(lèi)型
4.在throws過(guò)程中,如果有方法try-catch,就相當(dāng)于處理異常,就可以不必throws
五、自定義異常
基本概念
當(dāng)程序中出現(xiàn)了某些“錯(cuò)誤”,但該錯(cuò)誤信息并沒(méi)有在Throwable子類(lèi)中描述處理,這個(gè)時(shí)候可以自己設(shè)計(jì)異常類(lèi),用于描述該錯(cuò)誤信息
自定義異常的步驟
1.定義類(lèi):自定義異常類(lèi)名繼承Exception或RuntimeException
2.如果繼承Exception,屬于編譯異常
3.如果繼承RuntimeException,屬于運(yùn)行異常(一般來(lái)說(shuō),繼承RuntimeException)
六、throw和throws的區(qū)別
意義 | 位置 | 后面跟的東西 | |
throws | 異常處理的一種方式 | 方法聲明處 | 異常類(lèi)型 |
throw | 手動(dòng)生成異常對(duì)象的關(guān)鍵字 | 方法體中 | 異常對(duì)象 |
到此這篇關(guān)于Java中的異常Exception詳細(xì)解析的文章就介紹到這了,更多相關(guān)Java異常Exception內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java并發(fā)請(qǐng)求下數(shù)據(jù)插入重復(fù)問(wèn)題的解決方法
現(xiàn)在遇到一個(gè)項(xiàng)目,移動(dòng)設(shè)備存儲(chǔ)數(shù)據(jù),然后一起上傳,那就出現(xiàn)了許多重復(fù)數(shù)據(jù),這篇文章主要給大家介紹了關(guān)于java并發(fā)請(qǐng)求下數(shù)據(jù)插入重復(fù)問(wèn)題的解決方法,需要的朋友可以參考下2021-11-11Java中使用Lambda表達(dá)式和函數(shù)編程示例
這篇文章介紹了Java中使用Lambda表達(dá)式和函數(shù)編程示例,該文章會(huì)演示多個(gè)示列,分別是變量聲明上下文中的lambda、return語(yǔ)句上下文中的lambda、賦值上下文中的lambda、lambda在數(shù)組初始值設(shè)定項(xiàng)上下文中的用法等等,需要的朋友可以參考一下2021-10-10