一篇文章帶你深入了解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. 在操作之前就做充分的檢查.(先請示,再行動(dòng))
<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 代碼塊中的代碼用于處理善后工作, 會(huì)在最后執(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 代碼塊中的程序就不會(huì)繼續(xù)執(zhí)行, 而是交給 catch 中的代碼來執(zhí)行. catch 執(zhí)行完畢會(huì)繼續(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)異常, 就會(huì)結(jié)束 try 中的代碼, 看和 catch 中的異常類型是否匹配.
3.如果找到匹配的異常類型, 就會(huì)執(zhí)行 catch 中的代碼
4.如果沒有找到匹配的異常類型, 就會(huì)將異常向上傳遞到上層調(diào)用者.
5.無論是否找到匹配的異常類型, finally 中的代碼都會(huì)被執(zhí)行到(在該方法結(jié)束之前執(zhí)行).
6.如果上層調(diào)用者也沒有處理的了異常, 就繼續(xù)向上傳遞.
7.一直到 main 方法也沒有合適的代碼處理異常, 就會(huì)交給 JVM 來進(jìn)行處理, 此時(shí)程序就會(huì)異常終止.
3.拋出異常(使用throw關(guān)鍵字)
在寫代碼時(shí),有時(shí)候需要手動(dòng)拋出異常(例如登錄界面)示例:
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.自定義異常通常會(huì)繼承自 Exception 或者 RuntimeException
2.繼承自 Exception 的異常默認(rèn)是受查異常
3.繼承自 RuntimeException 的異常默認(rèn)是非受查異常.
總結(jié)
本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!
相關(guān)文章
Java如何使用Query動(dòng)態(tài)拼接SQL詳解
這篇文章主要給大家介紹了關(guān)于Java如何使用Query動(dòng)態(tài)拼接SQL的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-01-01基于java時(shí)區(qū)轉(zhuǎn)換夏令時(shí)的問題及解決方法
下面小編就為大家分享一篇基于java時(shí)區(qū)轉(zhuǎn)換夏令時(shí)的問題及解決方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-11-11SpringBoot通過源碼探究靜態(tài)資源的映射規(guī)則實(shí)現(xiàn)
這篇文章主要介紹了SpringBoot通過源碼探究靜態(tài)資源的映射規(guī)則實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05