1. 程式人生 > >Java Exception 和Error

Java Exception 和Error

con 代碼實現 and 關閉 multi 試圖 正常 過程 res

(事先聲明:該文章並非完全是我自己的產出,更多的是我個人在看到資料後通過理解並記錄下來,作為自己閱讀後的一個筆記;我現在試圖對自己多年工作中的知識點做一個回顧,希望能融會貫通)

(此文參考<Java核心技術36講>第二講)

Exception & Error

Java的Exception和Error都繼承了Throwable,且僅有Throwable類能被拋出(throw)和捕獲(catch)。

Error是指正常情況下不會發現的,並且發現後無法恢復;此類錯誤不需要捕獲,如:OutOfMemoryError,StackOverflowError,正常代碼中無法對此類錯誤進行捕獲。

Exception一搬是指程序運行是出現的意外情況 - 該事件發生是在意料之中的,且有可能恢復;可以進行捕獲並相應處理。如: NumberFormatException, ValidateException(自定義). 異常又分為可檢查(checked)和不檢查(un-checked)。

1. Checked:在編譯時會強制要求進行捕獲,如在方法中有定義拋出的異常,則調用該方法時需要捕獲該異常並進行處理。

    public void methodA() throws ValidateException {
        // do thing
        throw new
ValidateException("Number exception"); } public void handleException() { ExceptionHandling eh = new ExceptionHandling(); eh.methodA(); // <--- need catch the exception here }

2. Un-checked: 運行時出現的異常,如在處理對象時發現對象為空(NullPointException),或者ClassCastException,此類異常通常不會在編譯時要求顯式處理。而是根據代碼實現者的具體實現來捕獲。

Exception處理 - try-with-resources

基本的語法有 try-catch-finally, throw new xxxException("Exception message"), throws xxxException (方法定義).

Java7之後,引入了try-with-resources: 當一個外部資源實現了Autocloseable / Closeable接口時,可以將原來復雜的try-catch-finally-try-catch替換成自動關閉。

舊的實現:

public void readFile(String fileName) {
    FileInputStream is = null;
    try {
        is = new FileInputStream(new File(fileName));
        log.info("File content:\n {}", is.read()); 
    }  catch(IOException e) {
        throw new RuntimeException(e.getMessage, e);
    } finally {
        if(is != null) {
            try {
                is.close();
            } catch (IOException e1) {
                throw new RuntimeException(e1.getMessage, e1);
            }
        }
    }
} 

新實現:

public void readFile(String fileName) {
    try (FileInputStream is = new FileinputStream(new File(fileName))) {
        log.info("File content:\n {}", is.read());
    } catch (IOException e) {
        throw new RuntimeException(e.getmessage, e);
    }
}

Exception處理 - Multiple exception

try {
    // do sth
} catch (IOException | ValidateException) {
    // handle exception here
}

日常使用建議

在日常編寫代碼過程中,處理異常應該盡量遵循一些好的經驗。

盡可能捕獲具體的異常,而不通用異常: 如Catch(NumberFormatException e), 而不是Catch(Exception e)

不要吞掉異常(Swallow Exception),應該輸出有用的信息。

盡早拋出異常,比如在正常代碼裏,如果一行代碼包含多個對象且出現NPE時, 很難判斷是哪個對象為空,因此可以在有可能出現對象為空且該對應一定不能為空時增加測試條件:

Preconditions.checkNotNull(neme, "neme can‘t be null");

Java Exception 和Error