天天看點

8.Java學習個人筆記----異常

第八章:異常

第一節:異常

1.1 異常概述

異常:在程式執行過程中,出現的非正常的情況,最終會導緻JVM的非正常停止

在Java等面向對象的程式設計語言中,異常本身就是一個類,産生異常就是建立異常對象并抛出了一個異常對象。Java處理異常的方式是中斷處理。

異常指的并不是文法錯誤,文法錯誤,編譯不通過,不會産生位元組碼檔案,根本不能運作。

1.2 異常體系

異常機制其實是幫助我們找到程式中的問題,異常的根類是

java.lang.Throwable

,其下有兩個子類:

java.lang.Error

java.lang.Exception

,平常所說的異常指

java.lang.Exception

Throwable體系:
  • **Error:**嚴重錯誤Error,無法通過處理的錯誤,隻能事先避免,好比絕症
  • **Execption:**表示異常,異常産生後程式員可以通過代碼的方式糾正,使程式繼續運作,是必須要處理的。好比感冒、闌尾炎

1.3 異常分類

**異常(Execption)的分類:**根據在編譯時期還是運作時期去檢查異常可以分為:

  • **編譯時期異常:

    CheckedExecption

    。**在編譯(寫代碼)時期就會檢查,如果沒有處理異常,則編譯失敗。(如日期格式化異常 )
  • **運作時期異常:

    RuntimeExecption

    。**在運作期間,檢查異常。在編譯時期,運作異常編譯器不會檢測(不報錯)。

錯誤的一種類型:

  • OutOfMemoryError

    :記憶體溢出的錯誤。使用的記憶體過大,超出了JVM配置設定的記憶體

1.4 異常的産生過程

當JVM檢測出程式會出現異常時,JVM會做兩件事情:

1、JVM會根據異常傳回的原因建立一個異常對象,這個異常對象包含了異常産生的内容、原因、位置

2、在

getElement

方法中,沒有異常的處理邏輯(try-catch),那麼JVM就會把異常對象抛出給方法的調用者main方法來處理這個異常

main方法接收到了這個異常對象,main方法也沒有異常的處理邏輯,繼續把對象抛出給main方法的調用者JVM處理

JVM接收到了這個異常對象,做了兩件事情:

1、把異常對象(内容、原因、位置)以紅色的字型列印在控制台

2、JVM會終止目前正在執行的java程式---->中斷處理

8.Java學習個人筆記----異常

第二節:異常的處理

java異常處理的五個關鍵字:

try、catch、finally、throw、throws

2.1 抛出異常throw

在java中,提供了一個throw關鍵字,它用來抛出一個指定的異常對象。

操作步驟:

1、建立一個異常對象,封裝一些提示資訊(資訊可以自己編寫)

2、需要将這個異常對象告知給調用者。通過關鍵字throw可以達到将異常傳遞到調用者處的目的。throw對象

throw用在方法内,用來抛出一個異常對象,将這個異常對象傳遞到調用者處,并結束目前方法的執行。

**throw關鍵字作用:**可以使用throw關鍵字在指定的方法中抛出指定的異常

使用格式:

注意:

1、throw關鍵字必須寫在方法的内部

2、throw關鍵字後邊的new的對象必須是Exception或者Exception的子類對象

3、throw關鍵字抛出指定的異常對象,我們就必須處理這個異常對象

  • throw關鍵字後邊建立的是RuntimeException或者是RuntimeException的子類對象,我們可以不處理,預設交給JVM處理(列印異常對象,中斷程式)
  • throw關鍵字後邊建立的是編譯異常(寫代碼的時候報錯),我們就必須處理這個異常,要麼throws,要麼try…catch

以後工作中,我們首先必須對方法傳遞過來的參數進行合法性校驗,如果參數不合法,那麼我們就必須使用抛出異常的方式,告知方法的調用者傳遞的參數有問題

注意:

NullPointerExecption

ArrayIndexOutOfBoundsException

都是運作期異常,我們不用處理,預設交給JVM處理

2.2 Objects非空判斷

Objects類由一些靜态的實用方法組成,這些方法是null-save(空指針安全的)或null-tolerant(容忍空指針的),那麼在它的源碼中,對對象為null的值進行了抛出異常操作

  • public static <T> requireNonNull(T obj)

    :檢視指定引用對象不是null
public static void method(Object object){
	if (object==null)
		throw new NullPointerException("傳遞的對象是null");
}

public static void methods(Object obj){
        Objects.requireNonNull(obj);
    	Objects.requireNonNull(obj,"傳遞的對象是null");
    }
}
           

2.3 聲明異常throws

**聲明異常:**将問題辨別出來,報告給調用者。如果方法内通過throw抛出了編譯時的異常,而沒有捕獲處理,那麼必須通過throws進行聲明,讓調用者去處理

關鍵字throws運用于方法聲明之上,用于表示目前方法不處理異常,而是提醒該方法的調用者來處理異常(抛出異常,自己不處理,交給别人處理),最終交給JVM處理---->中斷處理

**聲明異常的格式:**在方法聲明時使用

修飾符 傳回值類型 方法名(參數清單) throws 異常類名1,異常類名2...{
    throw new AAAException("産生原因");
    throw new BBBException("産生原因");
    ...
}
           

注意:

1、throws關鍵字必須寫在方法聲明上

2、throws關鍵字後邊聲明的異常必須是Exception或者是Exception的子類

3、方法内部如果抛出了多個異常對象,那麼throws後邊必須也聲明多個異常。如果抛出的多個異常對象有子父類關系,那麼直接聲明父類異常即可

4、調用了一個聲明抛出異常的方法,我們就必須處理聲明的異常,要麼繼續使用throws聲明抛出,交給方法的調用者處理,最終交給JVM,要麼try…catch自己處理異常

2.4 try…catch處理異常

**try…catch:**異常處理的第二種方式,自己處理異常

格式:

try{
    可能産生異常的代碼
}catch(定義一個異常的變量,用來接收try中抛出的異常對象){
    異常的處理邏輯,産生異常的對象之後,怎麼處理異常對象
    一般在工作中,會把異常的資訊記錄到一個日志中
}
...
    catch(異常類型 變量名){
        
    }
           

注意:

1、try中可能會抛出多個異常對象,那麼就可以使用多個catch來處理這些異常對象

2、如果try中産生了異常,那麼就會執行catch中的異常處理邏輯,執行完畢catch中的處理邏輯,繼續執行try…catch之後的代碼。如果try中沒有産生異常,那麼就不會執行catch中異常的處理邏輯,執行完try…catch之後的代碼

2.5 Throwable類中3個處理異常的方法

Throwable類中定義了一些檢視方法:

  • public String getMessage()

    :擷取異常的描述資訊,原因。提示給使用者看的時候,就提示的錯誤原因。簡短描述
  • public String toString()

    :擷取異常的類型和異常描述資訊(不用)。**預設調用toString方法。**詳細資訊
  • public void printStackTrace()

    :列印異常的跟蹤棧資訊并輸出到控制台。列印的資訊最為全面

2.6 finally代碼塊

**finally:**有一些特定的代碼無論異常是否發生,都需要執行。另外,因為異常會引發程式跳轉,導緻有些語句執行不到。而finally就是解決這個問題的,在finally代碼塊中存放的代碼都是一定會被執行的。

什麼時候的代碼必須最終執行?

當我們在try語句塊中打開了一些實體資源(磁盤檔案/網絡連接配接/資料庫連接配接等),我們都得在使用完成之後,最終關閉打開的資源

文法:

try{
    可能産生異常的代碼
}catch(定義一個異常的變量,用來接收try中抛出的異常對象){
    異常的處理邏輯,産生異常的對象之後,怎麼處理異常對象
    一般在工作中,會把異常的資訊記錄到一個日志中
}
...
    catch(異常類型 變量名){
        
    }finally{
        無論是否出現異常都會執行
    }
           

注意:

1、finally不能單獨使用,必須和try一起使用

2、finally一般用于資源釋放(資源回收),無論程式是否出現異常,最後都要資源釋放

2.7 異常的注意事項

  • 多個異常使用捕獲如何處理
    • 1、多個異常分别處理
    • 2、多個異常一次捕獲,多次處理
    • 3、多個異常一次捕獲一次處理
    一般我們是使用一次捕獲多次處理的方式,格式:
    try{
        異常1;
        異常2;
        ...
        異常n;
    }catch(){
        
    }catch(){
        
    }...
     catch(){
         
     }
               

一個try,多個catch注意事項:catch裡定義的異常變量,如果有父子關系,那麼子類的異常變量必須寫在上面,否則就會報錯

  • 運作時異常被抛出可以不處理,既不捕獲,也不聲明抛出,預設會給虛拟機處理,終止程式,什麼時候不抛出運作異常再來繼續執行程式
  • 如果finally有return語句,永遠傳回finally中的結果,應該避免該情況
  • 如果父類抛出了多個異常,子類覆寫父類的方法時,隻能抛出相同的異常或者是它的子類
  • 父類方法沒有抛出異常,子類覆寫父類該方法時也不可能抛出異常。此時子類産生該異常,隻能捕獲處理,不能聲明抛出
  • 在try/catch後可以追加finally代碼塊,其中的代碼一定會被執行,通常用于資源回收

第三節:自定義異常

什麼是自定義異常類:

在開發中根據自己業務的異常情況來定義異常類

異常類怎麼定義:

1、自定義一個編譯期異常:自定義類 并繼承于

java.lang.Exception

2、自定義一個運作時期的異常類:自定義類 并繼承于

java,langRuntimeException

格式:

public class XxxException extends Exception/RuntimeException{
    添加一個空參數的構造方法
	添加一個帶異常資訊的構造方法
}
           

注意:

1、自定義異常類一般都是以Exception結尾,說明該類是一個異常類

2、自定義異常類,必須繼承Exception或者RuntimeException

  • 繼承Exception:那麼自定義的異常類就是一個編譯期異常,如果方法内部抛出了編譯期異常,就必須處理這個異常,要麼throws,要麼try…catch
  • 繼承RuntimeException:那麼自定義的異常類就是一個運作期異常,無需處理,交給虛拟機處理(中斷處理)
public class RegisterException extends Exception{
    public RegisterException() {
    }

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