異常的基本用法
捕獲異常
基本語法
try{
有可能出現異常的語句 ;
}[catch (異常類型 異常對象) { } ... ]
[finally {
異常的出口
}]
- try 代碼塊中放的是可能出現異常的代碼.
- catch 代碼塊中放的是出現異常後的處理行爲.
- finally代碼塊中的代碼用於處理善後工作, 會在最後執行.
- catch 和 finally 都可以根據情況選擇加或者不加
- 方法之間是存在相互調用關係的, 這種調用關係我們可以用 “調用棧” 來描述. 在 JVM 中有一塊內存空間稱爲 “虛 擬機棧” 專門存儲方法之間的調用關係. 當代碼中出現異常的時候, 我們就可以使用 e.printStackTrace(); 的 方式查看出現異常代碼的調用棧.
- 一段代碼可能會拋出多種不同的異常, 不同的異常有不同的處理方式. 因此可以搭配多個 catch 代碼塊. 如果多個異常的處理方式是完全相同, 也可以寫成這樣
- Exception 類是所有異常類的父類.可以用這個類型表示捕捉所有異常.
- finally 表示最後的善後工作, 例如釋放資源,無論是否存在異常, finally 中的代碼一定都會執行到. 保證最終一定會執行到 Scanner 的 close 方法.
異常處理流程
- 程序先執行 try 中的代碼
- 如果 try 中的代碼出現異常, 就會結束 try 中的代碼, 看和 catch 中的異常類型是否匹配.
- 如果找到匹配的異常類型, 就會執行 catch 中的代碼
- 如果沒有找到匹配的異常類型, 就會將異常向上傳遞到上層調用者.
- 無論是否找到匹配的異常類型, finally 中的代碼都會被執行到(在該方法結束之前執行).
- 如果上層調用者也沒有處理的了異常,就繼續向上傳遞. 一直到 main 方法也沒有合適的代碼處理異常, 就會交給 JVM 來進行處理, 此時程序就會異常終止.
異常說明
我們在處理異常的時候, 通常希望知道這段代碼中究竟會出現哪些可能的異常.
我們可以使用 throws 關鍵字, 把可能拋出的異常顯式的標註在方法定義的位置. 從而提醒調用者要注意捕獲這些異常.
Java 異常體系
Java 內置了豐富的異常體系, 用來表示不同情況下的異常.
- 頂層類 Throwable 派生出兩個重要的子類, Error 和 Exception
- 其中 Error 指的是 Java運行時內部錯誤和資源耗盡錯誤. 應用程序不拋出此類異常. 這種內部錯誤一旦出現, 除了告知用戶並使程序終止之外, 再無能無力. 這種情況很少出現.
- Exception 是我們程序猿所使用的異常類的父類.
- 其中 Exception 有一個子類稱爲RuntimeException , 這裏面又派生出很多我們常見的異常類 NullPointerException , IndexOutOfBoundsException 等.
Java語言規範將派生於 Error 類或 RuntimeException 類的所有異常稱爲 非受查異常, 所有的其他異常稱爲 受查異常.
自定義異常類
- 自定義異常通常會繼承自 Exception 或者 RuntimeException
- 繼承自 Exception 的異常默認是受查異常
- 繼承自 RuntimeException 的異常默認是非受查異常.
實現一個用戶登陸功能.
ublic class Users {
private static String userName = "admin";
private static String password = "admin";
public static void main(String[] args) {
try {
login();
} catch (UsererrorException userError) {
userError.printStackTrace();
} catch (PassworderrorException passwordError) {
passwordError.printStackTrace();
}
}
public static void login() throws PassworderrorException,
UsererrorException {
Scanner scanner = new Scanner(System.in);
while ( true ) {
System.out.println("請輸入用戶名:");
String userName = scanner.nextLine();
System.out.println("請輸入密碼:");
String password = scanner.nextLine();
if ( ! users.userName.equals(userName) ) {
throw new UsererrorException("用戶名錯誤!");
}
if ( ! users.password.equals(password) ) {
throw new PassworderrorException("密碼錯誤!");
}
System.out.println("登陸成功");
}
}
}
class UsererrorException extends Exception {
public UsererrorException(String message) {
super(message);
}
}
class PassworderrorException extends Exception {
public PassworderrorException(String message) {
super(message);
}
}