Exception、Error、運行時異常與通常異常有何異同

轉自博客  https://blog.csdn.net/m0_37531231/article/details/79502778java

1、開場白

對於程序運行過程當中的可能出現異常狀況,java語言使用一種稱爲異常處理的錯誤捕捉機制進行處理。相信你們對 try { }catch( ){} finally{} 這種結構很是熟悉,使用頻率極高。既然常用它,並且也是面試常問知識點,咱們就有必要去深刻地瞭解一下。也談不上深刻,只是java語言的基本功。下面,開始吧!程序員

2、異常分類

在java中,異常對象都是派生於Throwable類的一個實例。若是java內置的異常類不可以知足需求,用戶還能夠建立本身的異常類。面試

下圖是java異常類層次結構圖 
這裏寫圖片描述
能夠看出,全部的異常都是由Throwable類,下一層分解爲兩個分支:Error和Exceprion。 
Error層次結構描述了java運行時系統的內部錯誤和資源耗盡錯誤。大多數錯誤與代碼編寫者執行的操做無關,而表示代碼運行時 JVM(Java 虛擬機)出現的問題。應用程序不該該拋出這種類型的對象。 
Exceprion這個層次結構又分解爲連個分支:一個分支派生於RuntimeException;另外一個分支包含其餘異常。劃分兩個分支的規則是:由程序錯誤致使的異常屬於RuntimeException;而程序自己沒有沒有問題,但因爲像I/O錯誤這類異常致使的異常屬於其餘異常。 
常見的RuntimeException(運行時異常): 
IndexOutOfBoundsException(下標越界異常) 
NullPointerException(空指針異常) 
NumberFormatException (String轉換爲指定的數字類型異常) 
ArithmeticException -(算術運算異常 如除數爲0) 
ArrayStoreException - (向數組中存放與聲明類型不兼容對象異常) 
SecurityException -(安全異常) 
IOException(其餘異常) 
FileNotFoundException(文件未找到異常。) 
IOException(操做輸入流和輸出流時可能出現的異常。) 
EOFException (文件已結束異常)數組

3、概念理解

首先明白下面的兩個概念 
unchecked exception(非檢查異常):包括運行時異常(RuntimeException)和派生於Error類的異常。對於運行時異常,java編譯器不要求必須進行異常捕獲處理或者拋出聲明,由程序員自行決定。 
checked exception(檢查異常,編譯異常,必需要處理的異常) 
也:稱非運行時異常(運行時異常之外的異常就是非運行時異常),java編譯器強制程序員必須進行捕獲處理,好比常見的IOExeption和SQLException。對於非運行時異常若是不進行捕獲或者拋出聲明處理,編譯都不會經過。安全

4、異常的處理

(1)、拋出異常app

一、調用一個拋出受查異常的方法必須用throws 子句聲明 調用method2()方法。 
二、程序運行過程當中發現錯誤,而且利用throw拋出一個受查異常 下面method2()方法。spa

@Test public void test() throws FileNotFoundException { method(); } public void method() throws FileNotFoundException { //一個會拋出異常的方法
 method2(); } //這裏 方法後是throws 
    public void method2() throws FileNotFoundException { //這裏是throw 
        throw new FileNotFoundException(); }

(2)、捕獲異常 
try { }catch( ){} finally{} 語句塊這就比較常見了。不在贅述。 
不過下面有一道有意思的題,實際使用中不太會碰見,面試題常見。 
來,看題!.net

 @Test public void test() { System.out.println(test11()); } public String test11() { try { System.out.println("try block"); return test12(); } finally { System.out.println("finally block"); } } public static String test12() { System.out.println("return statement"); return "after return"; }

答案: 
try block 
return statement 
finally block 
after return指針

@Test public void test() { System.out.println(test2()); } public  int test() { int b = 20; try { System.out.println("try block"); return b += 80; } catch (Exception e) { System.out.println("catch block"); } finally { System.out.println("finally block"); if (b > 25) { System.out.println("b>25, b = " + b); } return 200; } }

答案: 
try block 
finally block 
b>25, b = 100 
200code

總結:finally塊的語句在try或catch中的return語句執行以後返回以前執行且finally裏的修改語句可能影響也可能不影響try或catch中 return已經肯定的返回值,若finally裏也有return語句則覆蓋try或catch中的return語句直接返回。

5、實際開發中經常使用的一個模式

(1)、定義業務中出現的異常

分別是郵箱未註冊異常,驗證用戶信息異常和驗證密碼異常 
這裏寫圖片描述

(2)、模擬業務點會拋出這些異常,寫一個UserService

@Service public class UserService { @Autowired private UserRepository userRepository; public User getUserByUserId(int userId) throws EmailNotRegisterException, InvalidPasswordException, InvalidLoginInfoException { if(userId==0) throw new EmailNotRegisterException("郵箱沒有註冊"); if(userId==-1) throw new InvalidLoginInfoException("帳號不存在"); if(userId==-2) throw new InvalidPasswordException("密碼錯誤"); return userRepository.findUserByUserId(userId); } }

(3)在Controller層捕獲處理這些異常

@RestController @RequestMapping("/users") public class UserController { @Autowired private UserService userService; @RequestMapping(method = RequestMethod.GET) public ResponseEntity getUser() { User user= null; try { user = userService.getUserByUserId(1); } catch (EmailNotRegisterException e) { //TODO 作郵箱未註冊的處理
 ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getMessage()); } catch (InvalidPasswordException e) { //TODO 作驗證密碼失敗的處理
 ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getMessage()); } catch (InvalidLoginInfoException e) { //TODO 作驗證帳號失敗的處理
 ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getMessage()); } return ResponseEntity.ok().body(user); } }
相關文章
相關標籤/搜索