Mave 下載與安裝
異常
在Java中使用Exception類來描述異常。
Throwable是Java 語言中所有錯誤或異常的超類,即祖宗類。
異常繼承體系
Throwable -Error異常:錯誤--》無法處理,只能改程式碼 Exception異常 -RuntimeException以及子類:執行期異常,一旦發生只能修改程式碼 非RuntimeException:編譯期異常,可以處理
異常與錯誤的區別
異常:指程式在編譯、執行期間發生了某種異常(XxxException),我們可以對異常進行具體的處理。若不處理異常,程式將會結束執行。
public static void main(String[] args) {int[] arr = new int[3]; System.out.println(arr[0]); System.out.println(arr[3]); // 該句執行時發生了陣列索引越界異常ArrayIndexOutOfBoundsException,由於沒有處理異常,導致程式無法繼續執行,程式結束。 System.out.println("over"); // 由於上面程式碼發生了異常,此句程式碼不會執行 }
錯誤:指程式在執行期間發生了某種錯誤(XxxError),Error錯誤通常沒有具體的處理方式,程式將會結束執行。Error錯誤的發生往往都是系統級別的問題,都是jvm所在系統發生的,並反饋給jvm的。我們無法針對處理,只能修正程式碼。
public static void main(String[] args) { int[] arr = new int[1024*1024*100]; //該句執行時發生了記憶體溢位錯誤OutOfMemoryError,開闢了過大的陣列空間,導致JVM在分配陣列空間時超出了JVM記憶體空間,直接發生錯誤。 }
丟擲異常throw
使用格式:
throw new 異常類名(引數);
例如:
throw new NullPointerException("要訪問的arr陣列不存在"); throw new ArrayIndexOutOfBoundsException("該索引在陣列中不存在,已超出範圍");
l 異常類ArrayIndexOutOfBoundsException與NullPointerException的構造方法
class ArrayTools{ //通過給定的陣列,返回給定的索引對應的元素值。 public static int getElement(int[] arr,int index) { /* 若程式出了異常,JVM它會打包異常物件並丟擲。但是它所提供的資訊不夠給力。想要更清晰,需要自己丟擲異常資訊。 下面判斷條件如果滿足,當執行完throw丟擲異常物件後,方法已經無法繼續運算。這時就會結束當前方法的執行,並將異常告知給呼叫者。這時就需要通過異常來解決。 */ if(arr==null){ throw new NullPointerException("arr指向的陣列不存在"); } if(index<0 || index>=arr.length){ throw new ArrayIndexOutOfBoundsException("錯誤的角標,"+index+"索引在陣列中不存在"); } int element = arr[index]; return element; } }
class ExceptionDemo3 { public static void main(String[] args) { int[] arr = {34,12,67}; //建立陣列 int num = ArrayTools.getElement(null,2);// 呼叫方法,獲取陣列中指定索引處元素 //int num = ArrayTools.getElement(arr,5);// 呼叫方法,獲取陣列中指定索引處元素 System.out.println("num="+num);//列印獲取到的元素值 } }
宣告異常throws
宣告異常格式:
修飾符 返回值型別 方法名(引數) throws 異常類名1,異常類名2… { }
class Demo{ /* 如果定義功能時有問題發生需要報告給呼叫者。可以通過在方法上使用throws關鍵字進行宣告。 */ public void show(int x)throws Exception { if(x>0){ throw new Exception(); } else { System.out.println("show run"); } } }
throws用於進行異常類的宣告,若該方法可能有多種異常情況產生,那麼在throws後面可以寫多個異常類,用逗號隔開。
多個異常的情況,例如: public static int getElement(int[] arr,int index) throws NullPointerException, ArrayIndexOutOfBoundsException { if(arr==null){ throw new NullPointerException("arr指向的陣列不存在"); } if(index<0 || index>=arr.length){ throw new ArrayIndexOutOfBoundsException("錯誤的角標,"+index+"索引在陣列中不存在"); } int element = arr[index]; return element; }
捕獲異常try…catch…finally
捕獲異常格式:
try { //需要被檢測的語句。 } catch(異常類 變數) { //引數。 //異常的處理語句。 } finally { //一定會被執行的語句。 }
try:該程式碼塊中編寫可能產生異常的程式碼。
catch:用來進行某種異常的捕獲,實現對捕獲到的異常進行處理。
finally:有一些特定的程式碼無論異常是否發生,都需要執行。另外,因為異常會引發程式跳轉,導致有些語句執行不到。而finally就是解決這個問題的,在finally程式碼塊中存放的程式碼都是一定會被執行的。
class ExceptionDemo{ public static void main(String[] args){ //throws ArrayIndexOutOfBoundsException try { int[] arr = new int[3]; System.out.println( arr[5] );// 會丟擲ArrayIndexOutOfBoundsException 當產生異常時,必須有處理方式。要麼捕獲,要麼宣告。 } catch (ArrayIndexOutOfBoundsException e) { //括號中需要定義什麼呢?try中丟擲的是什麼異常,在括號中就定義什麼異常型別。 System.out.println("異常發生了"); } finally { arr = null; //把陣列指向null,通過垃圾回收器,進行記憶體垃圾的清除 } System.out.println("程式執行結果"); } }
l try catch finally組合:檢測異常,並傳遞給catch處理,並在finally中進行資源釋放。
l try catch組合 : 對程式碼進行異常檢測,並對檢測的異常傳遞給catch處理。對異常進行捕獲處理。
l 一個try 多個catch組合 : 對程式碼進行異常檢測,並對檢測的異常傳遞給catch處理。對每種異常資訊進行不同的捕獲處理。
注意:這種異常處理方式,要求多個catch中的異常不能相同,並且若catch中的多個異常之間有子父類異常的關係,那麼子類異常要求在上面的catch處理,父類異常在下面的catch處理。
l try finally 組合: 對程式碼進行異常檢測,檢測到異常後因為沒有catch,所以一樣會被預設jvm丟擲。異常是沒有捕獲處理的。但是功能所開啟資源需要進行關閉,所有finally。只為關閉資源。
執行時期異常
l RuntimeException和他的所有子類異常,都屬於執行時期異常。NullPointerException,ArrayIndexOutOfBoundsException等都屬於執行時期異常.
l 執行時期異常的特點:
方法中丟擲執行時期異常,方法定義中無需throws宣告,呼叫者也無需處理此異常
執行時期異常一旦發生,需要程式人員修改原始碼.
異常在方法重寫中細節
子類覆蓋父類方法時,如果父類的方法宣告異常,子類只能宣告父類異常或者該異常的子類,或者不宣告。
當父類方法宣告多個異常時,子類覆蓋時只能宣告多個異常的子集
當被覆蓋的方法沒有異常宣告時,子類覆蓋時無法宣告異常的。
package com.orcal.demo02; import java.sql.SQLException; public class Fu { public void f(){ } public void ff() throws SQLException{ } }
package com.orcal.demo02; import java.sql.SQLWarning; public class Zi extends Fu{ public void f(){//子類重寫父類方法沒有拋異常的方法時,重寫後不能拋異常 try { ff();//呼叫了拋異常方法 } catch (SQLWarning e) { // TODO Auto-generated catch block e.printStackTrace(); } } //重寫拋異常方法,重寫後可以不拋異常.如果拋,只能丟擲父類異常或父類異常的子類 public void ff() throws SQLWarning{} }
異常中常用方法
l getMessage方法:返回該異常的詳細資訊字串,即異常提示資訊
l toString方法:返回該異常的名稱與詳細資訊字串
l printStackTrace:在控制檯輸出該異常的名稱與詳細資訊字串、異常出現的程式碼位置
package com.orcal.demo01; public class Demo03 { public static void main(String[] args) { int[] arr={1,2,3}; try{ int n=get(arr); System.out.println(n); }catch(Exception ex){ System.out.println(ex.getMessage());//返回異常資訊 //System.out.println(ex);//toString返回異常類名和異常資訊 //ex.printStackTrace();//將異常類名。資訊。位置以紅字方式列印在控制檯 }finally{//final.finlize.finally System.out.println("一定會被執行的語句"); } System.out.println("你好"); } public static int get(int[] arr) throws Exception{ if(arr.length<5){ throw new Exception("你的陣列長度不夠!"); } int num=arr[4]; return num; } }
自定義異常
NullPointerException異常類原始碼:
public class NullPointerException extends RuntimeException { public NullPointerException() { super();//呼叫父類構造方法 } public NullPointerException(String s) { super(s);//呼叫父類具有異常資訊的構造方法 } }
定義個自己的異常,即自定義異常。
格式:
Class 異常名 extends Exception{ //或繼承RuntimeException public 異常名(){ } public 異常名(String s){ super(s); } }
class MyException extends Exception{ /* 為什麼要定義建構函式,因為看到Java中的異常描述類中有提供對異常物件的初始化方法。 */ public MyException(){ super(); } public MyException(String message) { super(message);// 如果自定義異常需要異常資訊,可以通過呼叫父類的帶有字串引數的建構函式即可。 } }
l 自定義異常繼承RuntimeException
class MyException extends RuntimeException{ /* 為什麼要定義建構函式,因為看到Java中的異常描述類中有提供對異常物件的初始化方法。 */ MyException(){ super(); } MyException(String message) { super(message);// 如果自定義異常需要異常資訊,可以通過呼叫父類的帶有字串引數的建構函式即可。 } }