1. 程式人生 > >Java入門之異常的處理

Java入門之異常的處理

1.異常的定義

1.定義:Java語言將程式執行過程中所發生的不正常嚴重錯誤稱為異常,對異常的處理稱為異常處理。

2.特點:它會中斷正在執行的程式,正因為如此異常處理是程式設計中一個非常重要的方面,也是程式設計的一大難點。

2.異常的分類

分類:異常分為error(錯誤類,該類通常不需程式設計師解決)和Exception(異常,這是程式設計師程式設計的錯誤,需要程式設計師自己解決)。 Exception的分類:分為RuntimeException(執行時錯誤)和非RuntimeException(檢查時錯誤) 四種分類的介紹: error類:指合理的應用程式在執行過程中發生的嚴重問題。當程式發生這種嚴重錯誤時,通常的做法是通知使用者並中止程式的執行。 RutimeException類:RuntimeException:執行時異常,即程式執行時丟擲的異常。這種異常在寫程式碼時不進行處理,Java原始檔也能編譯通過。 RuntimeException異常類及其下面的子類均為執行時異常。 非RuntimeException(CheckedException):檢查時異常,又稱為非執行時異常,這樣的異常必須在程式設計時進行處理,否則就會編譯不通過。Exception異常類及其子類(除去RuntimeException異常類及其子類)都是檢查時異常。 常見異常

在這裡插入圖片描述

3.異常的處理

1)Java中對異常的處理有如下兩種方式: 1.通過try、catch和finally關鍵字捕獲異常; 2.通過throw或throws關鍵字丟擲異常。

4.捕獲異常

1.try ,catch,finally的語法:

try{
      //可能丟擲異常的語句塊
}catch(SomeException1 e){ // SomeException1特指某些異常 
     //當捕獲到SomeException1型別的異常時執行的語句塊
} catch( SomeException2 e){
     //當捕獲到SomeException2型別的異常時執行的語句塊
}finally{
     //無論是否發生異常都會執行的程式碼
}

2.語法結構:try…catch…finally異常處理結構中,try語句塊是必須的, catch和finally語句塊至少出現一個。

注意:如果try語句塊包含的是檢查時異常,則在沒有通過throws丟擲該異常類的情況下,try必須和catch一起使用,當該行程式碼去掉或登出掉時,catch相應的異常語句塊必須去掉

如下:

public class Test {
	
	public static void main(String[] args){
		try {
			Class.forName("java.lang.Object");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}
  1. 多重catch的特點: try語句塊中的程式碼可能會引發多種型別的異常,當引發異常時,會按順序檢視每個 catch 語句,並執行第一個與異常型別匹配的catch語句,其後 catch 語句被忽略
public class TestException {

	public static void main(String[] args) {
		try {
			String[] nameArray = { "小王", "小李", "小高" };
			for (int i = 0; i < 4; i++) {
				System.out.println(nameArray[i]);
			}
		} catch (ArrayIndexOutOfBoundsException e) {// 捕獲下標越界異常
			System.out.println("發生陣列下標越界異常,成功捕獲!");
		} catch (RuntimeException e) {// 捕獲執行時異常
			System.out.println("發生執行時異常,成功捕獲!");
		} catch (Exception e) {// 捕獲所有異常
			System.out.println("發生異常,成功捕獲!");
		}
		System.out.println("顯示完畢!");
	}
}
  1. finally關鍵字: Java異常在try/catch塊後加入finally塊,可以確保無論是否發生異常 finally塊中的程式碼總能被執行。
public class TestException {

	public static void main(String[] args) {
		try {
			String[] nameArray = { "小王", "小李", "小高" };
			for (int i = 0; i < 4; i++) {
				System.out.println(nameArray[i]);
			}
		} catch (ArrayIndexOutOfBoundsException e) {
			System.out.println("資料下標越界,請修改程式!");
			System.out.println("呼叫異常物件的getMessage()方法:");
			System.out.println(e.getMessage());
			System.out.println("呼叫異常物件的printStackTrace()方法:");
			e.printStackTrace();
			return;// finally語句塊仍然執行
			// System.exit(1);//直接退出JVM,finally語句塊不再執行
		} finally {
			System.out.println("顯示完畢!");
		}
		System.out.println("顯示完畢!");
	}
}

  1. final ,finally,finalize三個關鍵字的區別:
  2. final—修飾符(關鍵字),修飾的類不能被繼承,修飾的方法不能被重寫,修飾的變數為常量。
  3. finally—在異常處理時提供 finally 塊來執行任何清除操作。
  4. finalize—方法名,finalize() 方法在垃圾收集器將物件從記憶體中清除之前做必要的清理工作,如下程式碼:
class Student {
 
	@Override
	protected void finalize() throws Throwable {
		super.finalize();
		System.out.println("物件從記憶體中清除之前執行");
	}
}
 
public class Test {
 
	public static void main(String[] args) {
		new Student();
		System.gc();//執行該程式碼,垃圾收集器將回收未使用的記憶體空間。
	}
}

5. 丟擲異常

1)throw關鍵字:throw用於丟擲具體異常類的物件*** ,一般用於方法體中。 2)作用:當所寫的程式碼因不滿足某些條件致使程式無法執行時可以藉助throw丟擲一個異常物件提醒程式設計師。 3)注意:throw關鍵字一般用在方法體中,也可以用在程式碼塊中,但如果程式碼塊中丟擲的異常物件是由檢查時異常*建立的,則必須使用try-catch進行處理。

public class Test {

	int a = 9;
	int b = 0;
	{
		if (b == 0) {
			try {
				throw new Exception("操作失敗:分母不能為0");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		System.out.println(a / b);
	}

	public static void main(String[] args) {
		new Test();
	}
}

4)throw丟擲的物件

  1. 拋給自己(用try,catch捕獲異常)
public class Test {

	int a = 9;
	int b = 0;
	{
		if (b == 0) {
			throw new UnsupportedOperationException("操作失敗:分母不能為0");
		}
		System.out.println(a / b);
	}

	public static void main(String[] args) {
		new Test();
	}
}
  1. 拋給方法的呼叫者(即該方法呼叫時會出現異常)
import javax.print.PrintException;

public class PrintUtil {

	public  static void printAge(int age) throws PrintException {//此處由於該方法使用throw丟擲的是由檢查時異常建立的物件並且throw後沒有自行處理,所以這裡必須要使用throws丟擲建立該異常的異常類;此處也可以throws 
		if (age >= 150 || age <= 0) {
			throw new PrintException("列印失敗,請輸入0~150之間的數");
		} else {
			System.out.println("年齡為:" + age);
		}
	}
}

注意:使用throw丟擲異常物件如果沒有try-catch捕獲該異常物件,則該丟擲異常物件語句執行後其所在方法結束執行。

public class Test {

public static void main(String[] args) {
	div(1, 0);
	System.out.println("程式碼2");
}

static void div(int a, int b){
	if(b==0){
		throw new UnsupportedOperationException("第二個引數不能為0");
	}
	System.out.println("程式碼1");
}
}
  1. throws的用法:throws用於宣告方法可能丟擲的異常,其後為異常類,可以有多個,異常類之間用英文逗號間隔。
  2. 作用: 1) 當方法體中的throw關鍵字丟擲由檢查時異常建立的物件時,如果該異常物件在丟擲的同時已經通過try-catch進行了處理,則可以不使用throws,否則必須使用throws丟擲建立該物件的異常類或其父類。 2) 所呼叫的方法丟擲了檢查時異常時,如果該方法在呼叫的同時已經通過try-catch進行了處理,則可以不使用throws繼續上拋該異常,否則必須使用throws才能上拋該異常,此時上拋的異常類可以是呼叫方法時方法丟擲的異常類也可以是其父類。

注:如果方法中的異常已經通過try-catch進行了捕獲則無需再使用throws上拋該異常了,否則即使上拋也無效,只會做無用功。

6.自定義異常類

做法:建立繼承Exception 或其子類的自定義類;自定義異常類呼叫父類建構函式(通常是含有一個String型別引數的建構函式,使得錯誤資訊能在異常類物件printStackTrace方法和getMessage方法中使用。)

//這是自定義的異常
public class AgeException extends Exception{
	public AgeException (String message) {
		super(message);
	}
}
//測試自定義異常
public class Test{

	public static void main(String[] args) {
		//throw new AgeException("");//throw只能用於方法,否則用try處理
		try {
			throw new AgeException("");
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}