1. 程式人生 > >java檔案操作及異常處理

java檔案操作及異常處理

Java異常框架Java異常架構圖:

1. Throwable
Throwable是 Java 語言中所有錯誤或異常的超類。
Throwable包含兩個子類: Error 和 Exception。它們通常用於指示發生了異常情況。
Throwable包含了其執行緒建立時執行緒執行堆疊的快照,它提供了printStackTrace()等介面用於獲取堆疊跟蹤資料等資訊。

2. Exception
Exception及其子類是 Throwable 的一種形式,它指出了合理的應用程式想要捕獲的條件。

3. RuntimeException
RuntimeException是那些可能在 Java 虛擬機器正常執行期間丟擲的異常的超類。
編譯器不會檢查RuntimeException異常。例如,除數為零時,丟擲ArithmeticException異常。RuntimeException是ArithmeticException的超類。當代碼發生除數為零的情況時,倘若既"沒有通過throws宣告丟擲ArithmeticException異常",也"沒有通過try...catch...處理該異常",也能通過編譯。這就是我們所說的"編譯器不會檢查RuntimeException異常"!
如果程式碼會產生RuntimeException異常,則需要通過修改程式碼進行避免。例如,若會發生除數為零的情況,則需要通過程式碼避免該情況的發生!

4. Error
和Exception一樣,Error也是Throwable的子類。它用於指示合理的應用程式不應該試圖捕獲的嚴重問題,大多數這樣的錯誤都是異常條件。
和RuntimeException一樣,編譯器也不會檢查Error。
Java將可丟擲(Throwable)的結構分為三種類型:被檢查的異常(Checked Exception),執行時異常(RuntimeException)和錯誤(Error)。

(1) 執行時異常
定義: RuntimeException及其子類都被稱為執行時異常。
特點: Java編譯器不會檢查它。也就是說,當程式中可能出現這類異常時,倘若既"沒有通過throws宣告丟擲它",也"沒有用try-catch語句捕獲它",還是會編譯通過。例如,除數為零時產生的ArithmeticException異常,陣列越界時產生的IndexOutOfBoundsException異常,fail-fail機制產生的ConcurrentModificationException異常等,都屬於執行時異常。
     雖然Java編譯器不會檢查執行時異常,但是我們也可以通過throws進行宣告丟擲,也可以通過try-catch對它進行捕獲處理。
     如果產生執行時異常,則需要通過修改程式碼來進行避免。例如,若會發生除數為零的情況,則需要通過程式碼避免該情況的發生!

(2) 被檢查的異常
定義: Exception類本身,以及Exception的子類中除了"執行時異常"之外的其它子類都屬於被檢查異常。
特點: Java編譯器會檢查它。此類異常,要麼通過throws進行宣告丟擲,要麼通過try-catch進行捕獲處理,否則不能通過編譯。例如,CloneNotSupportedException就屬於被檢查異常。當通過clone()介面去克隆一個物件,而該物件對應的類沒有實現Cloneable介面,就會丟擲CloneNotSupportedException異常。
     被檢查異常通常都是可以恢復的。

(3) 錯誤
定義: Error類及其子類。
特點: 和執行時異常一樣,編譯器也不會對錯誤進行檢查。
     當資源不足、約束失敗、或是其它程式無法繼續執行的條件發生時,就產生錯誤。程式本身無法修復這些錯誤的。例如,VirtualMachineError就屬於錯誤。
     按照Java慣例,我們是不應該是實現任何新的Error子類的!
對於上面的3種結構,我們在丟擲異常或錯誤時,到底該哪一種?《Effective Java》中給出的建議是:對於可以恢復的條件使用被檢查異常,對於程式錯誤使用執行時異常。

  1. 案例一:檔案操作及異常處理
    public class After {
           // 讀取C盤下test.txt檔案
        public static void method() {
            FileReader fr = null;
            BufferedReader br = null;
            try {
                // 1.開啟FileReader
                fr = new FileReader("C:\\test.txt");
                // 2.開啟BufferedReader
                br = new BufferedReader(fr);
                String line = br.readLine();
                // 輸出檔案內容
                while (line != null) {
                    System.out.println(line);
                    line = br.readLine();
                }
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                // 與開啟資源順序逆方向關閉資源
                try {
                    // 3.關閉BufferedReader
                    if (br != null) {
                        br.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    // 4.關閉FileReader
                    if (fr != null) {
                        try {
                            fr.close();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

知識點: 

1.throws是在定義方法時候丟擲異常,throw是在方法體內丟擲異常 
2.try{}catch(Exception e){}finally{}這是一個比較常見的組合

使用try-catch-finally組合注意點: 
• 當不存在catch語句時,finally 語句必須存在並且緊跟在try語句後面。 
• 在try語句和catch語句間不能存在任何語句,同樣在catch語句和finally語句中也不能存在任何語句 ,這地方的語句不包括註釋語句。 
• 當不存在catch語句時,finally語句必須存在並且緊跟在 try語句後面。在try語句和catch語句間不能存在任何語句。

自定義異常型別 
MyException.java

public class MyException extends Exception
{
  public MyException()
  {

  }
  public MyException(String s)
  {
        super(s);
  }

}

寫一個可能丟擲異常的方法 
ExceptionClass.java

public class ExceptionClass
{
  public String setNumber(int number) throws MyException
    {
        if(number >= 0 && number <=100)
        {
            return "正常";
        }
        else
        {
            throw new MyException("輸入錯誤");
        }
    }

}

呼叫該方法 
MainClass.java

public class MainClass
{
   public static void main (String args[])
    {
        try{
            ExceptionClass exception = new ExceptionClass();
            //設定0-100範圍數字
            String s = exception.setNumber(90);
            System.out.println(s);
        }
        catch(MyException e)
        {
            System.out.println("異常資訊為:"+e.getMessage());
        }
    }
}