一篇文章帶你深入了解Java異常
一.初識異常
1.常見的異常類型
<1>除以0
System.out.println(10/0); // 執(zhí)行結(jié)果 Exceptioninthread"main"java.lang.ArithmeticException: /byzero
<2>數(shù)組下標(biāo)越界
int[] arr= {1, 2, 3};
System.out.println(arr[100]);
// 執(zhí)行結(jié)果
Exceptioninthread"main"java.lang.ArrayIndexOutOfBoundsException: 100
<3>訪問null對象
publicclassTest {
publicintnum=10;
publicstaticvoidmain(String[] args) {
Testt=null;
System.out.println(t.num);
}
}
// 執(zhí)行結(jié)果
Exceptioninthread"main"java.lang.NullPointerException
2.防御式編程
<1>LBYL
Look Before You Leap. 在操作之前就做充分的檢查.(先請示,再行動)
<2>EAFP
It's Easier to Ask Forgiveness than Permission. “事后獲取原諒比事前獲取許可更容易”. 也就是先操作, 遇到問題再處理.(先斬后奏)
二.異常的基本用法
1.捕獲異常
<1>基本語法:
try{
有可能出現(xiàn)異常的語句 ;
}[catch (異常類型異常對象) {} ... ]
[finally {
異常的出口}]
注意事項(xiàng):
1.try 代碼塊中放的是可能出現(xiàn)異常的代碼.
2.catch 代碼塊中放的是出現(xiàn)異常后的處理行為.
3.finally 代碼塊中的代碼用于處理善后工作, 會在最后執(zhí)行.
4.其中 catch 和 finally 都可以根據(jù)情況選擇加或者不加.
<2>try catch代碼示例
int[] arr= {1, 2, 3};
try {
System.out.println("before");
System.out.println(arr[100]);
System.out.println("after");
} catch (ArrayIndexOutOfBoundsExceptione) { // 打印出現(xiàn)異常的調(diào)用棧
e.printStackTrace();
}
System.out.println("after try catch");
// 執(zhí)行結(jié)果
before
java.lang.ArrayIndexOutOfBoundsException: 100
atdemo02.Test.main(Test.java:10)aftertrycatch
一旦 try 中出現(xiàn)異常, 那么 try 代碼塊中的程序就不會繼續(xù)執(zhí)行, 而是交給 catch 中的代碼來執(zhí)行. catch 執(zhí)行完畢會繼續(xù)往下執(zhí)行.
注意:catch可以有多個(gè),也可以再一個(gè)catch中捕獲多個(gè)異常
<3>try catch finally代碼示例
int[] arr= {1, 2, 3};
try {
System.out.println("before");
arr=null;
System.out.println(arr[100]);
System.out.println("after");
} catch (Exceptione) {
e.printStackTrace();
} finally {
System.out.println("finally code");}
// 執(zhí)行結(jié)果
before
java.lang.NullPointerException
atdemo02.Test.main(Test.java:12)finallycode
finally 表示最后的善后工作, 例如釋放資源
finally是一定執(zhí)行的代碼(即使try中含有return語句)
例如:
publicstaticintfunc() { try {
return10;
} finally {
return20;
}
}
// 執(zhí)行結(jié)果20
2.異常的處理流程
1.程序先執(zhí)行 try 中的代碼
2.如果 try 中的代碼出現(xiàn)異常, 就會結(jié)束 try 中的代碼, 看和 catch 中的異常類型是否匹配.
3.如果找到匹配的異常類型, 就會執(zhí)行 catch 中的代碼
4.如果沒有找到匹配的異常類型, 就會將異常向上傳遞到上層調(diào)用者.
5.無論是否找到匹配的異常類型, finally 中的代碼都會被執(zhí)行到(在該方法結(jié)束之前執(zhí)行).
6.如果上層調(diào)用者也沒有處理的了異常, 就繼續(xù)向上傳遞.
7.一直到 main 方法也沒有合適的代碼處理異常, 就會交給 JVM 來進(jìn)行處理, 此時(shí)程序就會異常終止.
3.拋出異常(使用throw關(guān)鍵字)
在寫代碼時(shí),有時(shí)候需要手動拋出異常(例如登錄界面)示例:
publicstaticintdivide(intx, inty) {
if (y==0) {
thrownewArithmeticException("拋出除 0 異常"); }
returnx/y;
}
三.java異常體系
1.java內(nèi)置異常
下圖表示 Java 內(nèi)置的異常類之間的繼承關(guān)系:

1.頂層類 Throwable 派生出兩個(gè)重要的子類, Error 和 Exception
2.其中 Error 指的是 Java 運(yùn)行時(shí)內(nèi)部錯(cuò)誤和資源耗盡錯(cuò)誤. 應(yīng)用程序不拋出此類異常. 這種內(nèi)部錯(cuò)誤一旦出現(xiàn),除了告知用戶并使程序終止之外, 再無能無力. 這種情況很少出現(xiàn).
3.Exception 是異常類的父類.
4.其中 Exception 有一個(gè)子類稱為 RuntimeException , 這里面又派生出很多我們常見的異常類,NullPointerException , IndexOutOfBoundsException 等.
注意:
1Java語言規(guī)范將派生于 Error 類或 RuntimeException 類的所有異常稱為 非受查異常, 所有的其他異常稱為 受查異常.如果一段代碼可能拋出 受查異常, 那么必須顯式進(jìn)行處理.
2.自定義異常類
創(chuàng)建一個(gè)類,繼承內(nèi)置異常類,實(shí)現(xiàn)自定義異常
例如寫一個(gè)用戶登錄功能Login:
public static void main(String[] args) {
try {
login("admin", "123456");
} catch (UserError userError) {
userError.printStackTrace();
} catch (PasswordError passwordError) {
passwordError.printStackTrace();
}
}
public static void login(StringuserName, Stringpassword) throwsUserError, PasswordError {
if (!Test.userName.equals(userName)) {
throw new UserError("用戶名錯(cuò)誤");
}
if (!Test.password.equals(password)) {
throw new PasswordError("密碼錯(cuò)誤");
}
System.out.println("登陸成功");
}
class UserError extends Exception {
publicUserError(Stringmessage) {
super(message);
}
}
class PasswordError extends Exception {
public PasswordError(Stringmessage) {
super(message);
}
}
注意:
1.自定義異常通常會繼承自 Exception 或者 RuntimeException
2.繼承自 Exception 的異常默認(rèn)是受查異常
3.繼承自 RuntimeException 的異常默認(rèn)是非受查異常.
總結(jié)
本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Java數(shù)據(jù)結(jié)構(gòu)BFS廣搜法解決迷宮問題
廣搜BFS的基本思想是: 首先訪問初始點(diǎn)v并將其標(biāo)志為已經(jīng)訪問。接著通過鄰接關(guān)系將鄰接點(diǎn)入隊(duì)。然后每訪問過一個(gè)頂點(diǎn)則出隊(duì)。按照順序,訪問每一個(gè)頂點(diǎn)的所有未被訪問過的頂點(diǎn)直到所有的頂點(diǎn)均被訪問過。廣度優(yōu)先遍歷類似與層次遍歷2022-04-04
java Long類型轉(zhuǎn)為String類型的兩種方式及區(qū)別說明
這篇文章主要介紹了java Long類型轉(zhuǎn)為String類型的兩種方式及區(qū)別說明,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
Spring AOP如何實(shí)現(xiàn)注解式的Mybatis多數(shù)據(jù)源切換詳解
這篇文章主要給大家介紹了關(guān)于Spring AOP如何實(shí)現(xiàn)注解式的Mybatis多數(shù)據(jù)源切換的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-11-11
java實(shí)現(xiàn)對服務(wù)器的自動巡檢郵件通知
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)對服務(wù)器的自動巡檢郵件通知,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-05-05
Springboot集成Kafka實(shí)現(xiàn)producer和consumer的示例代碼
這篇文章主要介紹了Springboot集成Kafka實(shí)現(xiàn)producer和consumer的示例代碼,詳細(xì)的介紹了什么是Kafka和安裝Kafka以及在springboot項(xiàng)目中集成kafka收發(fā)message,感興趣的小伙伴們可以參考一下2018-05-05
Spring?Boot+RabbitMQ?通過fanout模式實(shí)現(xiàn)消息接收功能(支持消費(fèi)者多實(shí)例部署)
這篇文章主要介紹了Spring?Boot+RabbitMQ?通過fanout模式實(shí)現(xiàn)消息接收(支持消費(fèi)者多實(shí)例部署),本文通過案例場景分析給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
Spring Cloud基于zuul實(shí)現(xiàn)網(wǎng)關(guān)過程解析
這篇文章主要介紹了Spring Cloud基于zuul實(shí)現(xiàn)網(wǎng)關(guān)過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12

