注:本文轉載自coder-pig
原文請戳:http://blog.csdn.net/coder_pig/article/details/22728889
大家好,今天天氣很熱,所以就待在家裏學習,順便接着上篇文章繼續學習java。一步兩步,一步兩步,一步一步似爪牙,似魔鬼的步伐。。。咳咳,開始嘍
Java異常與斷言
前言
在前面三節的學習中,對於面向對象的編程思想已告一段落了;
從前面的學習我們都知道,Java具有安全,可靠兩個優點,一部分原因是因爲
Java摒棄了指針這個概念,還有垃圾回收機制;還有一個原因是因爲Java提供了異常處理機制
在這一節中,我們將會對異常與斷言這兩個關鍵詞進行解析!
本節學習路線圖:
學習路線解析:
①瞭解異常是什麼東東,熟悉幾個常見的異常,學會使用try-catch,finally,throws和throw對異常進行處理;學會自定義異常
②瞭解斷言的好處,以及斷言的啓動,關閉
異常:
什麼是異常?
程序運行過程中出現的不正常現象!例如:除法運算時,除以0,這個就是算術異常
記住:異常時運行時的程序出錯,編譯時檢查的僅僅是語法錯誤!不運行而來的異常?
爲什麼會出現異常?
程序運行過程中由於各種因素導致程序運行發生錯誤,比如用戶的錯誤操作,代碼本身錯誤,系統環境因素等;
在處理異常時需要對異常進行判斷,針對不同的異常類型採取不同的處理措施!
異常的分類:
異常處理機制模型
常見的異常信息總結
ArithmeticException | 算術異常 |
ArrayIndexOutOfBoundsException | 數組下標越界異常 |
ArrayStoreException | 數組元素類型不兼容eg:爲整型數組賦浮點型的數 |
ClassCastException | 類型強制轉換異常(精度丟失) |
ClassNotFoundException | 找不到對應類異常 |
CloneNotSupportedException | 調用clone()方法,但沒有實現Cloneable接口(ps:數組默認實現該接口) |
EOFException | 文件已結束異常 |
FileNotFoundException | 找不到對應文件異常 |
IllegalAccessException | 否問某個類被拒絕時的異常(eg:在別的類中訪問private修飾的類) |
IndexOutOfBoundsException | 下標索引越界異常(eg:數組int a[5],訪問a[5]);就會觸發該異常,因爲下標從0開始 |
InstantiationException | 使用newInstance()方法創建抽象類或藉口實例拋出的異常 |
IOException | 輸入輸出異常 |
NullPointerException | 空指針異常,這個是比較常見的,eg:對象沒有實例化直接調用屬性或者方法 |
NumberFormatException | 數字格式轉換異常,eg:"1+2"這個是字符串,轉化爲數字就報錯了 |
NoSuchFieldException | 字段未找到異常 |
NoSuchMethodException | 方法爲找到異常 |
NoSuchElementException | 元素未找到異常(eg:調用StringTokenizer的nextToken()方法可以出現) |
SecurityException | 安全異常問題,可能需要修改權限 |
SQLException | 數據庫操作異常 |
StringIndexOutOfBoundsException | 字符串索引越界異常 |
MalformedURLException | URL配置異常(可能是URL協議,格式,或者路徑錯誤;jar包問題,去掉gnujaxp.jar包引用即可) |
UnknowHostException | 域名解析出錯異常 |
IllegArgumentException | 向方法傳遞了一個不合法或者不合理的參數 |
IllegalStateException | 違法的狀態異常,調用了某個不處於合法調用狀態的方法(eg:調用已經銷燬的方法) |
檢驗異常與非檢驗異常
Error類:表示一個程序錯誤,指的是底層的,低級的,不可以恢復的嚴重錯誤;此時的程序一定會退出,因爲已經失去了
程序運行所需的物理環境;我們無法進行處理
Exception類:分爲檢驗異常和非檢驗異常
RuntimeException及其子類都是非檢驗異常,其他的異常均爲檢驗異常,需要進行捕獲
檢驗異常:程序代碼中需要進行捕獲的異常,(try-catch或者throws + try - catch)
非檢驗異常:因爲沒有進行必要的檢查,由於疏忽或錯誤引起的異常,一定屬於虛擬機內部異常(eg:空指針異常)
異常的處理
異常的捕獲
try-catch塊
catch塊必須和try塊一起使用,不能單獨使用
代碼示例:數組越界異常
- package com.jay.example;
- /*
- * 該代碼演示的使用try-catch來捕獲數組越界異常
- * 如果沒加try和catch,那麼後面的HeHe是不會打印的,因爲
- * 因爲數組越界程序會直接終止,加了try-catch,如果發生了異常
- * 那麼就會執行catch裏面的方法;
- * 如果把a[5]改成a[4]木有異常,那麼catch塊就不會執行了
- * */
- public class ExceptionTest1 {
- public static void main(String[] args) {
- int a[] = {1,2,3,4,5};
- try
- {
- System.out.println(a[5]);
- }
- catch(ArrayIndexOutOfBoundsException e)
- {
- System.out.println("數組越界啦!!!!");
- }
- System.out.println("HeHe");
- }
- }
運行截圖:
finally塊
不能單獨使用,需要與try搭配,無論什麼情況,finally塊中的內容一定會執行,通常在finally塊中執行一些系統資源清理和釋放的工作
如:文件關閉,數據庫關閉等
注意:有特殊!如果在catch塊中調用了System.exit(0);方法,那麼finally部分的代碼不會被執行,因爲程序已經終止了
代碼示例:算術異常
- package com.jay.example;
- /*
- * 該代碼演示的是finally塊的使用
- * 需要跟這一個try,無論異常是否發生
- * 都會執行,只有在catch塊中調用了System.exit(0);
- * 方法才能阻止finally執行;
- * 通常是在該方法中完成系統資源的清理釋放
- * */
- public class ExceptionTest2 {
- public static void main(String[] args) {
- int x = 10;
- int y = 0;
- try
- {
- System.out.println(x/y);
- }
- catch(ArithmeticException e)
- {
- System.out.println("除數不能爲0,算術異常!");
- }
- //可自己刪掉try中的語句,或者在前面的catch中添加System.exit(0)來測試
- //finally什麼時候執行!
- finally
- {
- System.out.println("finally無論是否異常都執行!");
- }
- }
- }
運行截圖:
多重catch塊
就是使用多個catch塊,依次捕獲不同的異常;
其實只有一個catch塊被執行,要把子類異常的catch需放在父類異常的catch前面哦!
- package com.jay.example;
- /*
- * 該代碼演示的是多重catch塊的捕獲
- * 代碼中故意犯了除0,數組下表越界,數字格式三個錯誤
- * 當程序發生錯誤了,依次尋找第一個匹配的異常
- * 子類的catch塊要放在父類的catch塊前面哦!
- * */
- public class ExceptionTest3 {
- public static void main(String[] args) {
- try
- {
- //現在報算數異常;如果把這部分註釋掉就會報數組越界異常
- int a = 1;
- int b = 0;
- System.out.println(a/b);
- //如果把這部分註釋掉,那麼會報數字格式異常
- int c[] = {1,2,3};
- System.out.println(c[3]);
- //如果把這部分註釋掉,就正常輸出了
- int d = Integer.parseInt("a");
- int e = Integer.parseInt("2");
- System.out.println(d + e);
- System.out.println("程序木有錯誤!");
- }
- catch(NumberFormatException ex){System.out.println("數字格式異常!");}
- catch(ArithmeticException ex){System.out.println("算數異常,不能除以0!");}
- catch(ArrayIndexOutOfBoundsException ex){System.out.println("數組下標越界異常!");}
- catch(Exception ex){System.out.println("其他異常");}
- }
- }
運行截圖:
try-catch塊的嵌套
就是try-catch裏面又有try-catch,這個和if-else的嵌套差不多,
效果和前面的多重catch塊差不多,比較簡單,這裏就不講了
- try
- {
- try
- {
- }catch(Exception e){}
- }catch(Exception e){}
異常聲明
throws迴避異常
當一個方法可能會引發某種異常時,但是我們又不想在該方法中對該異常進行處理;
可以用throws將異常拋出,當我們調用該異常時再對異常進行捕獲
代碼示例:
- package com.jay.example;
- /*
- * 帶代碼演示的是使用throws迴避方法中可能會出現的異常
- * 等調用方法時再對異常進行捕獲處理
- * */
- public class ExceptionTest4 {
- //再方法這裏使用throws迴避異常,就是說不在這裏對異常進行捕獲處理
- //還有這裏用static修飾是因爲main()方法是靜態方法,只能調用類中的靜態成員
- public static void show()throws ArrayIndexOutOfBoundsException
- {
- int a[] = {1,2,3};
- System.out.println(a[3]);
- }
- public static void main(String[] args) {
- //對方法中的異常進行捕獲!
- try{
- show();
- }catch(ArrayIndexOutOfBoundsException ex){System.out.println("數組越界異常!");}
- }
- }
異常拋出
throw顯式引發異常
部分讀者可能有個問題:程序沒異常不好麼?吃飽飯沒事做啊,爲什麼要自己去引發異常?
其實顯式拋出異常通常用於程序的調試或者拋出用戶自定義異常
自定義異常時用的比較多!
自定義異常
系統提供的異常類不一定能捕獲所有的錯誤異常,
在這種情況下,用戶可以根據自己的需要,自定義異常類型
自定義異常注意以下三點:
①自定義異常時,需要繼承Exception類
②由於是自定義異常,所以需要使用throw手動拋出自定義異常
③同事需要使用try-catch對異常進行捕獲
代碼示例:
- package com.jay.example;
- //繼承Exception父類,構造方法中super()裏面的
- //參數,可以通過MyException對異常進行捕獲
- class MyException extends Exception
- {
- public MyException() {
- super("自定義異常:除數不合規定");
- }
- }
- public class ExceptionTest5 {
- public static void main(String[] args) {
- int a = 2;
- int b = 1;
- //如果滿足一下情況就throw拋出異常,同時要用try-catch進行捕獲
- if(b == 0 || b == 1)
- {
- try {
- throw new MyException();
- } catch (MyException e) {
- System.out.println(e.getMessage());
- }
- }
- }
- }
運行截圖:
斷言
什麼是斷言?
jdk 1.4後,引入的Assert(斷言)的概念;允許在代碼中添加一些合法的語句
以用於調試程序;在assert指定的布爾表達式條件不成立時會會拋出
一個AssertionError對象,直接終止程序的運行!
使用斷言的好處?
一種錯誤處理機制,在程序開發與測試階段使用;
可以理解爲代替,if..else或者try-catch,因爲這些東東對程序的性能有一定影響
完成調試後還要將他們刪除,如果用斷言,則是最低代價
斷言的使用:
assert 條件
assert 條件:錯誤信息
第二種方式,如果前面的條件不成立的話,那麼後面的字符串作爲AssertionError錯誤輸出信息
斷言的開啓
默認情況下斷言是關閉的,要通過 enableassertions或-ea來啓用斷言功能
斷言的關閉
使用disableassertions或-da來關閉斷言功能
代碼示例
- public class AssertDemo {
- static void test(int num)
- {
- //如果num <= 0的話,拋出AssertError,顯示錯誤信息
- assert(num >=0):"傳入參數需要大於0";
- System.out.println("參數爲正數!");
- }
- public static void main(String[] args) {
- test(-7);
- }
- }
運行截圖:
代碼解析:
判斷某個參數是否爲正數,通過添加assert對參數進行判斷,表達式不成立的話輸出後面的錯誤信息
然後在cmd下調用斷言,-ea啓動斷言,-da關閉斷言
總結
在這一節中,我們對Java中的異常處理機制進行了解析,對異常處理模型和常見異常進行了瞭解
學會了使用try,catch,finally,throws,throw等關鍵字完成異常捕獲,處理,拋出,迴避等;
學習了自定義異常的使用;
最後還學習了一下斷言的基本用法;使用斷言時還有注意一下兩點:
①斷言失敗是致命,不可恢復的
②斷言檢查僅僅用於程序開發測試階段
建議還是少用!
好了,這一節就到這裏,如有紕漏,錯誤,好的建議;
請讀者指出,不勝感激!O(∩_∩)O謝謝!