一、異常概述
- 異常
1)錯誤(Error):一般指與虛擬機有關的問題。如系統崩潰、虛擬機錯誤、動態連接失敗等、這些錯誤產生時,因系統無法捕獲Error並處理,程序員將無能爲力,只能導致應用程序中斷。
2)異常(Exception):因編碼錯誤或外在因素導致的問題,這些問題能夠被系統捕獲並進行處理。例如:除以0,對負數開平方根、空指針訪問等。
a.非檢查型異常:編譯器不要求強制處置的異常。
該異常是因編碼或設計不當導致的,這種異常可以避免,RuntimeException及其所有子類都屬於非檢查異常。例如,數組下標越界異常、空指針訪問異常、算數異常、類型轉換不匹配異常。
b.檢查性異常:編譯器要求必須處置的異常。
該異常是程序運行時因外界因素而導致的,Exception及其子類(RuntimeException及其子類除外)都屬於檢查型異常。例如,數據庫訪問異常、文件操作異常、文件不存在異常、類沒找到異常。
檢查型異常體現了Java語言的嚴謹性,程序員必須對該類型的異常進行處理,否則程序編譯不通過,無法運行。
-
保存一致性數據
try
1)可能產生異常的語句/與數據一致性有關的語句
2)產生非託管資源的語句 -
catch
1)提示用戶產生異常的原因和可能的操作
2)異常處理
3)存入異常日誌
4)恢復一致性數據throw
5)是否再次拋出該異常throw,或拋出另一個不同的異常 -
Finally
回收非託管資源 -
日誌
1)異常日誌:爲維護人員排除bug
2)操作日誌:爲了安全
二、捕獲異常
try…catch語句
1.單catch處理語句
public class SingleCatchDemo {
public static void main(String[] args) {
try {
// 產生除以0的算數異常
int i = 10 / 0;
System.out.println("i的值爲:" + i);
} catch (Exception e) {
// 輸出異常信息
e.printStackTrace();
}
// 該條語句繼續執行
System.out.println("end");
}
}
- 多catch處理語句
import java.util.Scanner;
public class MultiCatchDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int array[] = new int[3];
try {
System.out.println("請輸入第1個數:");
// 從鍵盤獲取一個字符串
String str = scanner.next();
// 將不是整數數字的字符串轉換成整數,會引發NumberFormatException
int n1 = Integer.parseInt(str);
System.out.println("請輸入第2個數:");
// 從鍵盤獲取一個整數
int n2 = scanner.nextInt();
// 兩個數相除,如果n2是0,會引發ArithmeticException
array[1] = n1 / n2;
// 給a[3]賦值,數組下標越界,引發ArrayIndexOutOfBoundsException)
array[3] = n1 * n2;
System.out.println("兩個數的和是" + (n1 + n2));
} catch (NumberFormatException ex) {
System.out.println("數字格式化異常!");
} catch (ArithmeticException ex) {
System.out.println("算數異常!");
} catch (ArrayIndexOutOfBoundsException ex) {
System.out.println("下標越界異常!");
} catch (Exception ex) {
System.out.println("其他未知異常!");
}
System.out.println("程序結束!");
}
}
try…catch…finally語句
import java.io.FileInputStream;
import java.io.IOException;
public class FinallyDemo {
public static void main(String[] args) {
FileInputStream fis = null;
try {
// 創建一個文件輸入流,讀指定的文件
fis = new FileInputStream("zkl.txt");
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
// return語句強制方法返回
return; // ①
// 使用exit來退出應用
// System.exit(0); // ②
} finally {
// 關閉磁盤文件,回收資源
if (fis != null) {
try {
fis.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
System.out.println("執行finally塊裏的資源回收!");
}
}
}
自動關閉資源的try語句
import java.io.FileInputStream;
import java.io.IOException;
public class AutoCloseTryDemo {
public static void main(String[] args) {
// 自動關閉資源的try語句,JDK 7.0以上才支持
try (FileInputStream fis = new FileInputStream("zkl.txt")) {
// 對文件的操作...
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
// 包含了隱式的finally塊,fis.close()關閉資源
}
}
嵌套的try…catch語句
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Scanner;
public class NestingTryCatchDemo {
public static void main(String[] args) {
// 嵌套的try...catch語句
try {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入第1個數:");
// 從鍵盤獲取一個字符串
String str = scanner.next();
// 將不是整數數字的字符串轉換成整數,會引發NumberFormatException
int n1 = Integer.parseInt(str);
try {
FileInputStream fis = new FileInputStream("zkl.txt");
} catch (IOException ioe) {
System.out.println(ioe.getMessage());
}
System.out.println("請輸入第2個數:");
// 從鍵盤獲取一個整數
int n2 = scanner.nextInt();
System.out.println("您輸入的兩個數的商是:" + n1 / n2);
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("程序結束!");
}
}
多異常捕獲
代碼示例和多catch處理語句相同
三、拋出異常
throw拋出一個異常對象
throw是語句拋出一個異常,一般是在代碼塊的內部,當程序出現某種邏輯錯誤時由程序員主動拋出某種特定類型黨的異常。
import java.util.Scanner;
public class ThrowDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
System.out.println("請輸入年齡:");
// 從鍵盤獲取一個整數
int age = scanner.nextInt();
if (age < 0 || age > 80) {
// 拋出一個異常對象
throw new Exception("請輸入一個合法的年齡,年齡必須在0~80之間");
}
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("程序結束!");
}
}
throws聲明拋出異常序列
public class ThrowsDemo {
// 定義一個方法,該方法使用throws聲明拋出異常
public static void myThrowsFunction() throws NumberFormatException,
ArithmeticException, Exception {
Scanner scanner = new Scanner(System.in);
System.out.println("請輸入第1個數:");
// 從鍵盤獲取一個字符串
String str = scanner.next();
// 將不是整數數字的字符串轉換成整數,會引發NumberFormatException
int n1 = Integer.parseInt(str);
System.out.println("請輸入第2個數:");
// 從鍵盤獲取一個整數
int n2 = scanner.nextInt();
System.out.println("您輸入的兩個數相除的結果是:" + n1 / n2);
}
public static void main(String[] args) {
try {
// 調用帶拋出異常序列的方法
myThrowsFunction();
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (ArithmeticException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
四、自定義異常
自定義檢查型異常(繼承Exception)
public class AgeException extends Exception {
public AgeException() {
}
public AgeException(String msg) {
super(msg);
}
}
import java.util.Scanner;
public class MyExceptionDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
System.out.println("請輸入年齡:");
// 從鍵盤獲取一個整數
int age = scanner.nextInt();
if (age < 0 || age > 80) {
// 拋出一個自定義異常對象
throw new AgeException("年齡不合法,必須在0~80之間");
}
} catch (Exception ex) {
ex.printStackTrace();
}
System.out.println("程序結束!");
}
}
自定義非檢查型異常(繼承RuntimeException)
public class AgeException extends RuntimeException {
public AgeException() {
}
public AgeException(String msg) {
super(msg);
}
}