10個關於Java異常的常見問題

這篇文章總結了十個常常被問到的JAVA異常問題;java

1.檢查型異常VS非檢查型異常

簡單的說,檢查型異常是指須要在方法中本身捕獲異常處理或者聲明拋出異常由調用者去捕獲處理;程序員

非檢查型異常指那些不能解決的異常,如除0,空指針等;eclipse

檢查型異常很是重要,由於你但願使用你API接口的人知道如何處理這些異常;ide

舉個例子,IOException是很是常見的檢查型異常,RuntimeException是非檢查型異常;spa

Java的異常層級關係圖以下:指針

2.異常管理最佳實踐

若是一個異常當前可以被恰當的處理,那麼應該捕獲處理它,不然應該顯示的拋出異常;code

3.爲何在try代碼塊裏定義的變量,在catch或finally代碼塊裏不能被訪問

以下代碼,在try代碼塊中聲明字符串s變量,可是不能在catch代碼塊中使用,代碼不能編譯經過;orm

        try {
            File file = new File("path");
            FileInputStream fis = new FileInputStream(file);
            String s = "inside";
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            System.out.println(s);
        }

緣由是由於你不知道在try代碼塊中的哪一句會拋出異常,頗有可能這個異常在變量聲明以前就拋出了;對象

這正是以上這個例子的狀況;blog

注:強烈懷疑是由於做用域的關係致使s變量不可見;

4.爲何Integer.parseInt(null)和Double.parseDouble(null)會拋出不一樣的異常

這是JDK的問題,由於這兩個方法是不一樣的開發人員寫的,因此不必深究;

        Integer.parseInt(null);
        // throws java.lang.NumberFormatException: null
        Double.parseDouble(null);
        // throws java.lang.NullPointerException

注:其實我目前的JDK7已經沒有該問題了,兩個都是拋出NumberFormatException

5.多用運行時異常

幾個常見的運行時異常,如IllegalArgumentException、ArrayIndexOutOfBoundsException;

當判斷條件不知足時,能夠拋出這些異常,以下代碼:

        if (obj == null) {
            throw new IllegalArgumentException("obj can not be null");

6.是否能夠在一個catch代碼塊裏捕獲多個異常

答案是能夠的。由於JAVA的異常能夠追溯到同一個父類Exception,咱們可使用父類捕獲多個異常;

        try {
            
        } catch (Exception e) {
            // TODO: handle exception
        }

補充:

在JAVA7中,增長了新語法,能夠這樣捕獲多個異常:

try { 
  ...
} catch( IOException | SQLException ex ) { 
  ...
}

在JAVA7以前能夠這樣寫:

try {
  //.....
} catch (Exception exc) {
  if (exc instanceof IllegalArgumentException || exc instanceof SecurityException || 
     exc instanceof IllegalAccessException || exc instanceof NoSuchFieldException ) {

     someCode();

  } else if (exc instanceof RuntimeException) {
     throw (RuntimeException) exc;     

  } else {
    throw new RuntimeException(exc);
  }

}

7.構造方法是否能夠拋出異常

答案是能夠的,構造方法是一個特殊的方法,一樣能夠拋出異常;

注意,若是構造方法拋出異常,對象是沒有生成的;

8.finally語句塊一樣能夠拋出和捕獲異常

如下代碼是合法的:

    public static void main(String[] args) {
        File file1 = new File("path1");
        File file2 = new File("path2");
        try {
            FileInputStream fis = new FileInputStream(file1);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                FileInputStream fis = new FileInputStream(file2);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    }

可是出於可讀性考慮,最好把finally裏的異常處理代碼封裝到一個方法裏,而後調用該方法,以下代碼:

    public static void main(String[] args) {
        File file1 = new File("path1");
        File file2 = new File("path2");
        try {
            FileInputStream fis = new FileInputStream(file1);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            methodThrowException();
        }
    }

9.finally代碼塊裏是否能夠寫return語句

是的,能夠

10.爲何JAVA程序員常常悄悄地忽略異常的處理

如下代碼片斷會常常出如今程序中,若是異常處理那麼重要,爲何還會有這麼多開發人員一直這樣作呢?

        try {
            ...
        } catch (Exception e) {
            e.printStackTrace();
        }

常常出現的代碼並不表明是對的;

可能不少開發人員都使用eclipse的快速修復,自動生成異常處理代碼,如上所示,其實除了記錄下log,並無作什麼處理;

正如條目2所描述的,若是不能正確處理該異常的話,最好拋出異常,以便異常儘早被發現;

 

譯文連接:http://www.programcreek.com/2013/10/top-10-questions-about-java-exceptions/

相關文章
相關標籤/搜索