一.初識異常
1.常見的異常類型
<1>除以0
1
2
3
|
System.out.println( 10 / 0 ); // 執行結果 Exceptioninthread "main" java.lang.ArithmeticException: /byzero |
<2>數組下標越界
1
2
3
4
|
int [] arr= { 1 , 2 , 3 }; System.out.println(arr[ 100 ]); // 執行結果 Exceptioninthread "main" java.lang.ArrayIndexOutOfBoundsException: 100 |
<3>訪問null對象
1
2
3
4
5
6
7
8
9
|
publicclassTest { publicintnum= 10 ; publicstaticvoidmain(String[] args) { Testt= null ; System.out.println(t.num); } } // 執行結果 Exceptioninthread "main" java.lang.NullPointerException |
2.防御式編程
<1>LBYL
Look Before You Leap. 在操作之前就做充分的檢查.(先請示,再行動)
<2>EAFP
It's Easier to Ask Forgiveness than Permission. “事后獲取原諒比事前獲取許可更容易”. 也就是先操作, 遇到問題再處理.(先斬后奏)
二.異常的基本用法
1.捕獲異常
<1>基本語法:
1
2
3
4
5
|
try { 有可能出現異常的語句 ; }[ catch (異常類型異常對象) {} ... ] [ finally { 異常的出口}] |
注意事項:
1.try 代碼塊中放的是可能出現異常的代碼.
2.catch 代碼塊中放的是出現異常后的處理行為.
3.finally 代碼塊中的代碼用于處理善后工作, 會在最后執行.
4.其中 catch 和 finally 都可以根據情況選擇加或者不加.
<2>try catch代碼示例
1
2
3
4
5
6
7
8
9
10
11
12
13
|
int [] arr= { 1 , 2 , 3 }; try { System.out.println( "before" ); System.out.println(arr[ 100 ]); System.out.println( "after" ); } catch (ArrayIndexOutOfBoundsExceptione) { // 打印出現異常的調用棧 e.printStackTrace(); } System.out.println( "after try catch" ); // 執行結果 before java.lang.ArrayIndexOutOfBoundsException: 100 atdemo02.Test.main(Test.java: 10 )aftertrycatch |
一旦 try 中出現異常, 那么 try 代碼塊中的程序就不會繼續執行, 而是交給 catch 中的代碼來執行. catch 執行完畢會繼續往下執行.
注意:catch可以有多個,也可以再一個catch中捕獲多個異常
<3>try catch finally代碼示例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
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" );} // 執行結果 before java.lang.NullPointerException atdemo02.Test.main(Test.java: 12 )finallycode |
finally 表示最后的善后工作, 例如釋放資源
finally是一定執行的代碼(即使try中含有return語句)
例如:
1
2
3
4
5
6
|
publicstaticintfunc() { try { return10; } finally { return20; } } |
// 執行結果20
2.異常的處理流程
1.程序先執行 try 中的代碼
2.如果 try 中的代碼出現異常, 就會結束 try 中的代碼, 看和 catch 中的異常類型是否匹配.
3.如果找到匹配的異常類型, 就會執行 catch 中的代碼
4.如果沒有找到匹配的異常類型, 就會將異常向上傳遞到上層調用者.
5.無論是否找到匹配的異常類型, finally 中的代碼都會被執行到(在該方法結束之前執行).
6.如果上層調用者也沒有處理的了異常, 就繼續向上傳遞.
7.一直到 main 方法也沒有合適的代碼處理異常, 就會交給 JVM 來進行處理, 此時程序就會異常終止.
3.拋出異常(使用throw關鍵字)
在寫代碼時,有時候需要手動拋出異常(例如登錄界面)示例:
1
2
3
4
5
|
publicstaticintdivide(intx, inty) { if (y== 0 ) { thrownewArithmeticException( "拋出除 0 異常" ); } returnx/y; } |
三.java異常體系
1.java內置異常
下圖表示 Java 內置的異常類之間的繼承關系:
1.頂層類 Throwable 派生出兩個重要的子類, Error 和 Exception
2.其中 Error 指的是 Java 運行時內部錯誤和資源耗盡錯誤. 應用程序不拋出此類異常. 這種內部錯誤一旦出現,除了告知用戶并使程序終止之外, 再無能無力. 這種情況很少出現.
3.Exception 是異常類的父類.
4.其中 Exception 有一個子類稱為 RuntimeException , 這里面又派生出很多我們常見的異常類,NullPointerException , IndexOutOfBoundsException 等.
注意:
1Java語言規范將派生于 Error 類或 RuntimeException 類的所有異常稱為 非受查異常, 所有的其他異常稱為 受查異常.如果一段代碼可能拋出 受查異常, 那么必須顯式進行處理.
2.自定義異常類
創建一個類,繼承內置異常類,實現自定義異常
例如寫一個用戶登錄功能Login:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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( "用戶名錯誤" ); } if (!Test.password.equals(password)) { throw new PasswordError( "密碼錯誤" ); } 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 的異常默認是受查異常
3.繼承自 RuntimeException 的異常默認是非受查異常.
總結
本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關注服務器之家的更多內容!
原文鏈接:https://blog.csdn.net/qq_45704528/article/details/113120178