1. 程式人生 > >java基礎-中級(三)【異常】

java基礎-中級(三)【異常】

3、異常

3.1 Exception異常的劃分

3.2 檢查性異常和非檢查性異常

3.3 異常的基本方法

3.4 異常的捕獲和丟擲

3.5 finally關鍵字

3.6 自定義異常


3、異常

異常是程式中的一些錯誤,但並不是所有的錯誤都是異常,並且錯誤有時候是可以避免的。異常引起的原因有很多種,有使用者操作引起的,有的是程式錯誤引起的,有的是物理硬體引起的。大致將異常分為以下三種:

  • 檢查性異常:這種異常是程式設計師無法預見的,所以必須進行處理,不能夠被忽略。
  • 執行時異常:這種異常是程式在執行時發生的異常,這種異常可以預見,所有可以被忽略(編譯器忽略,並不是開發者)
  • 錯誤:錯誤不屬於異常,而是脫離開發者的控制範圍,錯誤在程式碼中經常被忽略,因為無法處理。

3.1 Exception異常的劃分

異常Exception的父類是Throwable類,Error類也是Throwable的一個子類。如下圖所示。Exception的子類包括執行時異常RuntimeException和檢查異常(有很多,例如IOException)。

3.2 檢查性異常和非檢查性異常

(1)非檢查性異常

檢查性異常是在編寫程式時,一旦有此異常必須進行處理(丟擲或捕獲),這種異常是不能被忽略的,下表中的異常都是非檢查性異常。

異常
描述
ClassNotFoundException 應用程式試圖載入類時,找不到相應的類,丟擲該異常。
CloneNotSupportedException 當呼叫 Object 類中的 clone 方法克隆物件,但該物件的類無法實現 Cloneable 介面時,丟擲該異常。
IllegalAccessException 拒絕訪問一個類的時候,丟擲該異常。
InstantiationException 當試圖使用 Class 類中的 newInstance 方法建立一個類的例項,而指定的類物件因為是一個介面或是一個抽象類而無法例項化時,丟擲該異常。
InterruptedException 一個執行緒被另一個執行緒中斷,丟擲該異常。
NoSuchFieldException 請求的變數不存在
NoSuchMethodException 請求的方法不存在

(2)檢查性異常

檢查性異常是程式編寫時,要依靠程式設計師的自身程式設計素養來判斷是否需要進行處理,而編譯程式的時候是無法發現的。如下表。

異常 描述
ArithmeticException 當出現異常的運算條件時,丟擲此異常。例如,一個整數"除以零"時,丟擲此類的一個例項。
ArrayIndexOutOfBoundsException 用非法索引訪問陣列時丟擲的異常。如果索引為負或大於等於陣列大小,則該索引為非法索引。
ArrayStoreException 試圖將錯誤型別的物件儲存到一個物件陣列時丟擲的異常。
ClassCastException 當試圖將物件強制轉換為不是例項的子類時,丟擲該異常。
IllegalArgumentException 丟擲的異常表明向方法傳遞了一個不合法或不正確的引數。
IllegalMonitorStateException 丟擲的異常表明某一執行緒已經試圖等待物件的監視器,或者試圖通知其他正在等待物件的監視器而本身沒有指定監視器的執行緒。
IllegalStateException 在非法或不適當的時間呼叫方法時產生的訊號。換句話說,即 Java 環境或 Java 應用程式沒有處於請求操作所要求的適當狀態下。
IllegalThreadStateException 執行緒沒有處於請求操作所要求的適當狀態時丟擲的異常。
IndexOutOfBoundsException 指示某排序索引(例如對陣列、字串或向量的排序)超出範圍時丟擲。
NegativeArraySizeException 如果應用程式試圖建立大小為負的陣列,則丟擲該異常。
NullPointerException 當應用程式試圖在需要物件的地方使用 null 時,丟擲該異常
NumberFormatException 當應用程式試圖將字串轉換成一種數值型別,但該字串不能轉換為適當格式時,丟擲該異常。
SecurityException 由安全管理器丟擲的異常,指示存在安全侵犯。
StringIndexOutOfBoundsException 此異常由 String 方法丟擲,指示索引或者為負,或者超出字串的大小。
UnsupportedOperationException 當不支援請求的操作時,丟擲該異常。

3.3 異常的基本方法

序號 方法及說明
1 public String getMessage()
返回關於發生的異常的詳細資訊。這個訊息在Throwable 類的建構函式中初始化了。
2 public Throwable getCause()
返回一個Throwable 物件代表異常原因。
3 public String toString()
使用getMessage()的結果返回類的串級名字。
4 public void printStackTrace()
列印toString()結果和棧層次到System.err,即錯誤輸出流。
5 public StackTraceElement [] getStackTrace()
返回一個包含堆疊層次的陣列。下標為0的元素代表棧頂,最後一個元素代表方法呼叫堆疊的棧底。
6 public Throwable fillInStackTrace()
用當前的呼叫棧層次填充Throwable 物件棧層次,新增到棧層次任何先前資訊中。

3.4 異常的捕獲和丟擲

(1)捕獲

使用 try 和 catch 關鍵字可以捕獲異常。try/catch 程式碼塊放在異常可能發生的地方。

try/catch程式碼塊中的程式碼稱為保護程式碼,使用 try/catch 的語法如下:

多重捕獲異常try/catch中按層次進行匹配,如果第一個catch中匹配後後面的catch就不會匹配,以此類推。注意:catch的層級是從小到大。

//單一捕獲異常
try
{
   // 程式程式碼
}catch(ExceptionName e1)
{
   //Catch 塊
}


//多重捕獲異常
try{
   // 程式程式碼
}catch(異常型別1 異常的變數名1){
  // 程式程式碼
}catch(異常型別2 異常的變數名2){
  // 程式程式碼
}catch(異常型別2 異常的變數名2){
  // 程式程式碼
}

(2)丟擲異常

異常的丟擲的關鍵字是throw/throws,其中throws是放在方法上的,而throw是在方法內部進行丟擲的。

import java.io.*;
public class className
{
  public void deposit(double amount) throws RemoteException {
    throw new RemoteException();
  }
}

3.5 finally關鍵字

finally 關鍵字用來建立在 try 程式碼塊後面執行的程式碼塊。無論是否發生異常,finally 程式碼塊中的程式碼總會被執行。也就是說,即使丟擲異常後,最終的結尾語句可以使用finally中進行編寫,可以處理一些例如IO流的關閉等操作。

注意下面事項:

  • catch 不能獨立於 try 存在。
  • 在 try/catch 後面新增 finally 塊並非強制性要求的。
  • try 程式碼後不能既沒 catch 塊也沒 finally 塊。
  • try, catch, finally 塊之間不能新增任何程式碼。

3.6 自定義異常

在 Java 中你可以自定義異常。編寫自己的異常類時需要記住下面的幾點。

  • 所有異常都必須是 Throwable 的子類。
  • 如果希望寫一個檢查性異常類,則需要繼承 Exception 類。
  • 如果你想寫一個執行時異常類,那麼需要繼承 RuntimeException 類。
public class Test {
    public static void main(String[] args)  {
        try {
            exception();
        } catch (MyException e) {
            e.printStackTrace();
            System.out.println(e.getMessage());
        }
    }
    static void  exception() throws MyException {
        throw new MyException("我的異常");
    }
}

列印結果:

MyException: 我的異常
	at Test.exception(Test.java:11)
	at Test.main(Test.java:4)
我的異常

後續將會學習專案的全域性處理異常。