Java程序基础——异常
目錄
目錄
1、異常
2、異常的繼承體系
3、異常與錯誤的區(qū)別
4、異常對象的產(chǎn)生原因及處理方式
5、拋出異常thorw
6、聲明異常throws
7、 捕獲異常 try ..catch...finally
8、異常處理的組合方式
9、finally代碼塊
10、調(diào)用拋出異常方法
11、運(yùn)行期異常
12、方法重寫時異常的處理
13、異常中常用方法
14、自定義異常類的定義
15、自定義異常的練習(xí)
1、異常
什么是異常?
- Java代碼在運(yùn)行時期發(fā)生的問題就是異常
- 異常類:在Java中,把異常信息封裝成了一個類,當(dāng)出現(xiàn)了問題時,就會胡藏劍異常對象,并拋出異常相關(guān)的信息(如異常出現(xiàn)的位置、原因等)
- 比如:ArrayIndedOutOfBoundsException
2、異常的繼承體系
- 在Java中,使用Exception類來描述異常。通過查詢API,發(fā)現(xiàn)Exception其實時Throwable的子類。Throwable是Java語言中所有錯誤或異常的父類。
- RuntimeException及其子類、只能在java程序運(yùn)行中出現(xiàn)
- Error是Throwable的子類,它與Exception平級,它用來表示Java程序中可能會產(chǎn)生的嚴(yán)重錯誤。解決辦法只有一個,就是修改代碼避免Error的產(chǎn)生。
3、異常與錯誤的區(qū)別
- ?異常:表示程序在編譯、運(yùn)行期間發(fā)生的某種異常(XXXException),我們可以對異常進(jìn)行具體的處理。若不處理異常,程序?qū)⒔Y(jié)束運(yùn)行。
- 錯誤:指程序在運(yùn)行期間發(fā)生了某種錯誤(XxxError),Error錯誤通常沒有具體的處理方式,程序?qū)Y(jié)束運(yùn)行。Error錯誤的發(fā)生往往都是系統(tǒng)級別的問題,我們無法針對處理,只能修改代碼。
4、異常對象的產(chǎn)生原因及處理方式
class ArrayTools{public static int getElement (int[] arr,int index) {int element = arr[index];return element;}public class ExceptionDemo{public static void main(String[] args) {int[] arr = {1,2,3};int element = ArrayTools.getElement(arr,4);System.out.println("element="+element);} }原因分析:
- 由于沒有找到索引【4】,導(dǎo)致運(yùn)行時發(fā)生了異常,這個異常JVM認(rèn)識:ArrayIndexOutOfBoundsException。這個異常Java本省有描述:異常的名稱、異常的內(nèi)容、異常產(chǎn)生的位置。? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?Java將這些信息直接封裝到異常對象中:new?ArrayIndexOutOfBoundsException(4);
- throw new?ArrayIndexOutOfBoundsException(4) 產(chǎn)生異常對象,JVM將產(chǎn)生的異常拋給調(diào)用者main()方法。
- main()方法接收到了數(shù)組索引越界異常對象。由于main()方法并沒有進(jìn)入處理異常,main()方法會繼續(xù)把異常拋給調(diào)用者JVM,當(dāng)JVM接收到異常后,將異常的名稱、異常的內(nèi)容、異常產(chǎn)生的位置都顯示在控制臺上,同時讓程序立刻終止。
異常的處理方式:
- JVM的默認(rèn)處理方式? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?將異常對象的名稱、原因、位置等信息輸出到控制臺,同時結(jié)束程序。一旦有異常發(fā)生,其后面的代碼不再執(zhí)行
- 解決程序中異常的手動方式
5、拋出異常thorw
在java中,提供了一個throw關(guān)鍵字,用來拋出一個指定的異常對象。
- 什么時候使用throw關(guān)鍵字?? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ——當(dāng)調(diào)用方法使用接受到的參數(shù)時,首先需要對參數(shù)數(shù)據(jù)進(jìn)行合法的判斷,數(shù)據(jù)若不合法,就應(yīng)該告訴調(diào)用者,傳遞合法的數(shù)據(jù)進(jìn)來。這時需要使用拋出異常的方式來告訴調(diào)用者。
- 使用throw關(guān)鍵字具體操作
throw用在方法內(nèi),用來拋出一個異常對象,將這個異常對象傳遞到調(diào)用者處,并結(jié)束當(dāng)前方法的執(zhí)行。
使用格式:
throw new 異常類名(參數(shù));?? ? ? ? ? ? ? ? ? ??
throw new NullPointerException("要訪問的數(shù)組不存在"); throw new ArrayIndexOutOfBoundsException("該索引在數(shù)組中不存在,已超出范圍"); public class ArrayTools {public static int getElement(int arr[],int index){if(arr==null){throw new NullPointerException("要訪問的數(shù)組不存在");}if(index < 0 || index >= arr.length){throw new ArrayIndexOutOfBoundsException("該索引"+index+"在數(shù)組中不不存在");}int element = arr[index];return element;} }public class ExceptionDemo {public static void main(String[] args) {int[] arr = {1,2,3};int element = ArrayTools.getElement(arr,4);System.out.println("element="+element);} }6、聲明異常throws
聲明:將問題表示出來,報告給調(diào)用者。如果方法內(nèi)通過throw拋出了編譯時異常,而沒有捕獲異常,那么必須通過throws進(jìn)行聲明,讓調(diào)用者去處理
聲明格式:
修飾符 返回值類型 方法名(參數(shù)) throws 異常類名1,異常類名2..{}注意事項:
throws用于進(jìn)行異常類的聲明,若該方法可能有多種異常情況產(chǎn)生,那么在throws后面可以寫多個異常類,用逗號隔開。
public void show(int x) throws Exception {if(x>0){throw new Exception() ;}else {System.out.println("x="+x);}}7、 捕獲異常 try ..catch...finally
捕獲:java中對異常有針對性的語句進(jìn)行捕獲,可以對出現(xiàn)的異常進(jìn)行指定方式的處理
捕獲異常格式:
try{// 需要被檢測的語句 }catch (異常類 變量){// 異常的處理語句 }finally {// 一定會被執(zhí)行的語句 }- try:該代碼塊中編寫可能產(chǎn)生異常的代碼
- catch:用來進(jìn)行某種異常的捕獲,實現(xiàn)對捕獲到的異常進(jìn)行處理
- finally:有一些特定的代碼無論異常是否發(fā)生,都需要執(zhí)行。另外,因為異常會引發(fā)程序跳轉(zhuǎn),導(dǎo)致有些語句不能執(zhí)行,而finally就是解決這個問題的。在finally代碼塊中的代碼都是一定會被執(zhí)行的!
- try...catch... 處理掉異常后,程序可以繼續(xù)執(zhí)行
8、異常處理的組合方式
- try..catch..finally:檢測異常,并傳遞給catch處理,最后在fianlly中進(jìn)行資源釋放。
- try..catch 組合:對代碼進(jìn)行異常檢測,并對檢測到的異常傳遞給catch處理。
- try..finally?組合:對代碼進(jìn)行異常檢測,由于沒有catch,一般會被默認(rèn)的JVM輸出。異常沒有捕獲處理,但是功能所開啟的資源需要進(jìn)行關(guān)閉,所以finally的存在是關(guān)閉資源。
- 一個try多個catch組合:對代碼快進(jìn)行異常檢測,并對檢測到的異常傳遞給catch處理。對每種異常信息進(jìn)行不同的捕獲處理。
多個catch處理的細(xì)節(jié):
多個catch小括號中,寫的是異常類的類名,它是由順序關(guān)系的
- 平級異常——拋出的異常類之間,沒有繼承關(guān)系,沒有順序
- 上下級關(guān)系的異常 ——越高級的父類,寫在越下面
9、finally代碼塊
特點:被finally控制的語句體一定會執(zhí)行
作用:無論程序是否有異常出現(xiàn),程序必須執(zhí)行釋放資源。如:IO流操作、數(shù)據(jù)庫操作。
10、調(diào)用拋出異常方法
有 try...catch 和 throws 兩種
在實際開發(fā)中使用哪種異常處理方式?
- 能自己處理的盡量自己處理。(建議使用 try...catch)
11、運(yùn)行期異常
1、概述:
- RuntimeException和它的所有子類異常,都屬于運(yùn)行期異常? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?如
- ArrayIndexOutOfBoundsException,NullPointerException 等都屬于運(yùn)行時期異常
2、特點:
- 方法中拋出運(yùn)行時期異常,方法定義中無需throws聲明,調(diào)用者也無需處理此異常。
- 運(yùn)行時期異常一旦發(fā)生,需要程序人員修改源代碼。
- 設(shè)計原因:運(yùn)行異常,不能發(fā)生,但如果發(fā)生了,程序人員要停止程序,修改源代碼。運(yùn)行異常一旦發(fā)生,后面的代碼沒有執(zhí)行的意義。
12、方法重寫時異常的處理
- 子類覆蓋父類方法時,如果父類的方法聲明異常,子類只能聲明父類異常或該異常的的子類,獲取不聲明。
- 當(dāng)父類方法聲明多個異常時,子類覆蓋時只能聲明多個異常的子集
- 當(dāng)覆蓋的方法沒有異常聲明時,子類覆蓋時無法聲明異常
- ?父類或接口中,沒有聲明異常,但子類覆蓋方法時發(fā)生了異常,怎么辦?
? ? ? ? 無法進(jìn)行throws聲明,只能catch捕獲。萬一問題處理不了,catch中繼續(xù)throw拋出,但是只能將異常轉(zhuǎn)換為RuntimeException子類拋出。
interface Inter{public abstract void method(); } public class Zi implements Inter{@Overridepublic void method() {int[] arr = null;if (arr == null){try {throw new Exception("數(shù)組不存在!");}catch (Exception e){System.out.println("父方法中沒有聲明異常,子類中不能拋出Exception異常");throw new RuntimeException(e);}}} }13、異常中常用方法
- getMessage():返回該異常的詳細(xì)信息字符串,即異常提示信息
- printStackTrace(): 在控制臺輸出該異常的名稱、詳細(xì)信息字符串、異常出現(xiàn)的代碼位置。
- toString():返回該異常的名稱與詳細(xì)信息字符串
14、自定義異常類的定義
class 異常名 extends Exception { // 或者繼承RuntimeExceptionpublic MyException(){super();} public MyException(String message){super(message);} }?自定義異常繼承RuntimeException:
public class MyRuntimeException extends RuntimeException{public MyRuntimeException(){super();}public MyRuntimeException(String message){super(message);} }15、自定義異常的練習(xí)
定義Person類,包含name和age兩個成員屬性
在Person類的有參構(gòu)造方法中,進(jìn)行年齡范圍的判讀,若年齡為負(fù)數(shù)或者大于100歲,則拋出NoAgeException異常,異常提示信息:“年齡數(shù)值非法”
要求:在測試類中,調(diào)用有參構(gòu)造方法,完成Person對象創(chuàng)建,并進(jìn)行異常處理
(1)自定義異常類NoAgeException?
public class NoAgeException extends Exception{public NoAgeException(){super();}public NoAgeException(String message){super(message);} }(2)自定義類Person
public class Person {private String name;private int age;public Person() {}public Person(String name, int age) throws NoAgeException {if(age<0 || age>200){throw new NoAgeException(age + "年齡數(shù)值非法");}this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}}(3)測試類
public class NoAgeExceptionDemo {public static void main(String[] args) {try {Person person = new Person("小鐳", 999);System.out.println(person.getAge());} catch (NoAgeException e) {e.printStackTrace();}} }構(gòu)造方法拋出的這個NoAgeException到底是繼承Exception,還是繼承RuntimeException?
- 繼承Exception,必須要throws聲明,告知調(diào)用者進(jìn)行捕獲,一旦問題處理了,調(diào)用者程序會繼續(xù)執(zhí)行
- 繼承RuntimeException,不需要throws聲明,這時調(diào)用是不需要寫捕獲異常代碼,因為調(diào)用者根本不知道有問題。一旦發(fā)生NoAgeException,調(diào)用者的程序會停掉,并由JVM將信息顯示到屏幕,讓調(diào)用者看到問題,修正代碼
總結(jié)
以上是生活随笔為你收集整理的Java程序基础——异常的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用OFBIZ的理由和不使用OFBIZ的
- 下一篇: 转载 CATransform3D 矩阵