1. 程式人生 > >Java異常的捕獲及處理---小總結

Java異常的捕獲及處理---小總結

一:異常的基本概念

二:異常的基本處理格式

三:異常的繼承結構

四:Java的異常處理機制

五:throws和throw關鍵字的作用

六:Exception和RunntimeException的區別

七:自定義異常類

八:斷言的作用和應用

1,為什麼需要異常處理?

異常是導致程式中斷執行的一種指令流。如果不對異常進行正確的處理,則可能導致程式的中斷執行,造成不必要的損失,所以
在程式的設計中必須要考慮各種異常的發生,並正確的做好相應的處理,這樣才能保證程式的正常執行。

一旦產生異常,異常之後的語句並不會被執行,而是直接結束程式,並將錯誤報告給客戶了。

2,異常的基本處理格式try—catch。try中捕獲異常,catch中處理對應的異常。

try中捕獲異常,出現異常之後的程式碼將不再被執行,而是跳轉到相應的catch語句中執行,用於處理異常。
對於異常,也可以設定其統一的出口,使用fially完成。

3,異常類的繼承關係

在整個Java的異常結構中實際上有兩個最常用的異常類,Exception,Error,這兩個類全都是Throwable的子類,
Exception,一般表示的是程式中出現的問題,可以直接使用try-catch處理。
Error,一般指的是JVM錯誤,程式中無法處理。
一般情況下,開發者習慣於將Error,Exception統一稱為異常。
一般在輸出異常資訊的時候,可以直接使用System.out.println進行列印異常物件。
首頁可以通過Exception提供的一個方法,public void printStackTrace();來列印異常資訊。

4,Java的異常處理機制:

在整個Java的異常處理中,實際上也是按照面向物件的方式進行處理的,處理步驟:
1,一旦產生異常,則首先會產生一個異常類的例項化物件。
2,在try語句中對此異常物件進行捕捉。
3,產生的異常物件與catch語句中的各個異常型別進行匹配,如果匹配成功則執行catch語句中的程式碼。

根據物件的多型性,子類的例項化物件可以直接使用父類的物件進行接收。
在異常的處理中,也是可以使用這樣的概念,因為try中產生的是一個例項化物件,如果現在有一些其他的無法知道
的異常,則可以最後使用Exception進行捕獲。
但是有一個注意點:捕獲更粗的異常要放在捕獲更細的異常之後。

又出現了一個問題:
既然所有的Exception物件都可以使用Exception接收,(都可以發生向上轉型關係)直接使用Exception捕獲異常不是更方便麼?
這樣雖然可以統一全部捕獲到異常,但是在一個精細的開發中,是不建議這樣使用的,因為,這樣只是知道發生了異常,並不知道
具體發生了什麼異常,所以,最好分別進行捕獲。

又有一個問題:
既然不過Exception是最方便的,那麼直接捕獲它的父類,Throwable豈不是更好?
首先,這樣的做法是可以的,因為Exception是Throwable的子類,但是正常的開發人員是不會這樣做的,因為程式的try語句中永遠只會丟擲Exception的子類物件,Throwable不僅僅有
Exception這個子類,還有Error這個子類。

1,程式出現異常之後,如果沒有合理的處理的話,則會導致程式的中斷執行。
2,使用try—catch,和try–catch–finally,可以處理異常。finally將會作為異常的統一出口,不管是否出現異常都會執行此語句。
3,一個異常處理中,可以同時出現多個catch,但是捕獲更粗的異常要放在捕獲更細的異常之後,否則程式編譯會報錯。
4,在異常中,最大的類Throwable,分為兩個子類,Exception,Error,其中Exception表示的是程式可以自己處理的異常,Error表示的是jvm錯誤,一般程式是無法處理的。
5,捕獲異常的時候,可以直接捕獲Exception,但是最好分開捕獲,如果所有的異常處理操作是一樣的話,則也可以直接捕獲Exception。
6,每當異常產生之後,會在程式中產生一個異常類的例項化物件,之後使用此物件與catch中的異常型別進行匹配,如果匹配成功則執行catch語句中的內容,如果匹配不成功,則
繼續向下匹配,如果都無法匹配成功,程式將出現中斷執行的情況。

5,在定義一個方法的時候,可以使用throws關鍵字宣告,使用throws宣告的方法表示此方法不處理異常,而是交給方法的呼叫處進行處理。

這樣一來,在後面呼叫這個除法的方法的時候就必須進行異常的處理。

throws使用格式: public 返回值型別 方法名稱(引數列表) throws 異常類{}

什麼意思呢?比如說,定義一個2個數相除的操作方法,對於這個除法操作,可能會出現除數為0的異常,但是也可能不出現異常,對於這樣的操作,
其實最好就是將它使用throws關鍵字宣告,一旦出現了異常,則應該交給呼叫處去處理。

class Math{
    public int div(int i,int j) throws Exception{   // 定義除法操作,如果有異常,則交給呼叫處處理
        int temp = i / j ;  // 計算,但是此處有可能出現異常
        return temp ;
    }
};

這樣一來,在後面呼叫這個除法的方法的時候就必須進行異常的處理。

那麼問題來了

這個div方法使用了throws宣告,就是說這個方法本身不做任何異常處理,如果產生異常交給呼叫處去處理,如果我呼叫處,呼叫這個方法,傳入的引數是正常的不會出現異常的引數的時候,也就是不會產生異常的情況下,我呼叫處沒有產生異常也就不進行異常處理,會有問題麼?
什麼意思呢?就是說,這樣的使用,會不會存在編譯錯誤?

class Math{
    public int div(int i,int j) throws Exception{   // 定義除法操作,如果有異常,則交給被呼叫處處理
        int temp = i / j ;  // 計算,但是此處有可能出現異常
        return temp ;
    }
};
public class ThrowsDemo02{
    // 呼叫處沒有進行異常的處理
    public static void main(String args[]){
        Math m = new Math() ;       // 例項化Math類物件
        System.out.println("除法操作:" + m.div(10,2)) ;
    }
};

結果:
這裡寫圖片描述
你瞧,編譯報錯了,這個地方,必須進行異常的處理,因為這裡有可能有異常,有可能沒異常,那麼,為了保證程式的正確執行,就必須進行異常的處理。

class Math{
    public int div(int i,int j) throws Exception{   // 定義除法操作,如果有異常,則交給被呼叫處處理
        int temp = i / j ;  // 計算,但是此處有可能出現異常
        return temp ;
    }
};
public class ThrowsDemo02{
    public static void main(String args[]){
        Math m = new Math() ;       // 例項化Math類物件
        try{
        System.out.println("除法操作:" + m.div(10,0));
        }catch(Exception e){
            e.printStackTrance();
        }

    }
};

這裡寫圖片描述
這樣一來,就不會有問題了。

如果,這樣的操作呢,在主方法中再使用throws關鍵字宣告,主方法也不處理任何的異常,會不會有問題?

class Math{
    public int div(int i,int j) throws Exception{   // 定義除法操作,如果有異常,則交給被呼叫處處理
        int temp = i / j ;  // 計算,但是此處有可能出現異常
        return temp ;
    }
};
public class ThrowsDemo02{
    // 在主方法中的所有異常都可以不使用try...catch進行處理
    public static void main(String args[]) throws Exception{
        Math m = new Math() ;       // 例項化Math類物件
        System.out.println("除法操作:" + m.div(10,2)) ;
    }
};

這裡寫圖片描述
編譯執行,
這也是沒問題的
如果出現了異常的時候

class Math{
    public int div(int i,int j) throws Exception{   // 定義除法操作,如果有異常,則交給被呼叫處處理
        int temp = i / j ;  // 計算,但是此處有可能出現異常
        return temp ;
    }
};
public class ThrowsDemo02{
    // 在主方法中的所有異常都可以不使用try...catch進行處理
    public static void main(String args[]) throws Exception{
        Math m = new Math() ;       // 例項化Math類物件
        System.out.println("除法操作:" + m.div(10,0)) ;
    }
};

這裡寫圖片描述
似乎和沒有使用異常處理的時候,打印出的是一個造型。

那麼問題又來了

主方法都沒有處理這異常,那異常到哪裡去了呢,誰去處理這個異常了呢?難道是jvm麼?
是的,其實就是jvm,在主程式中不處理任何的異常了,而是交給了它的上級,最大的頭,Java中最大的頭,就是jvm,所以,如果在主方法中使用了throws關鍵字,則表示一切的異常都交給jvm去處理,其實,Java預設的異常處理也是使用jvm完成的。

6,throw關鍵字

throw關鍵字的作用是在程式中丟擲一個異常,丟擲的是一個異常類的例項化物件。
使用了throw,丟擲了異常,必然要進行捕獲和處理,就是說,必須要進行try-catch處理。
在異常的處理中,try語句是捕獲異常,它捕獲的其實是一個異常類物件,那麼此異常物件也可以自己丟擲。
怎麼個意思呢?
查詢一下Java-doc看看exception的構造,發現,可以傳入一個String的message。
這裡寫圖片描述

public class ThrowDemo01{
    public static void main(String args[]){
        try{
            throw new Exception("自己拋著玩的。") ;    // 丟擲異常的例項化物件
        }catch(Exception e){
            System.out.println(e) ;
        }
    }
};

這裡寫圖片描述
如果不進行捕獲和處理這個丟擲的異常,編譯都不會通過:

public class ThrowDemo01{
    public static void main(String args[]){

            throw new Exception("自己拋著玩的。") ;    
    }
};

這裡寫圖片描述

在一般的開發中,try-catch-finally,throws,throw聯合使用是最多的。

比如,這樣的需求:現在對於兩個數的除法這個操作,要求,產生異常在方法呼叫處去處理異常,在計算前列印“開始計算”,在計算結束後,無論是否出現異常都列印“計算結束”,如果出現異常打印出異常資訊,如果沒有異常當然得打印出計算結果。

class Math{
    public int div(int i,int j) throws Exception{   // 定義除法操作,如果有異常,則交給被呼叫處處理
        System.out.println("***** 計算開始 *****") ;
        int temp = 0 ;  // 定義區域性變數
        try{
            temp = i / j ;  // 計算,但是此處有可能出現異常
        }catch(Exception e){
            throw e ;
        }finally{   // 不管是否有異常,都要執行統一出口
            System.out.println("***** 計算結束 *****") ;
        }
        return temp ;
    }
};
public class ThrowDemo02{
    public static void main(String args[]){
        Math m = new Math() ;
        try{
            System.out.println("除法操作:" + m.div(10,0)) ;
        }catch(Exception e){
            System.out.println("異常產生:" + e) ;
        }
    }
};

這裡寫圖片描述

7,Exception和RunntimeException的區別

先看看什麼是RunntimeException,檢視API,抓一個方法出來瞧瞧:

public static int parseInt(String s)
                    throws NumberFormatException

  Parses the string argument as a signed decimal integer. The characters in the string must all be decimal digits, except that the first character may be an ASCII minus sign '-' ('\u002D') to indicate a negative value or an ASCII plus sign '+' ('\u002B') to indicate a positive value. The resulting integer value is returned, exactly as if the argument and the radix 10 were given as arguments to the parseInt(java.lang.String, int) method.

Parameters: 

Returns: 
the integer value represented by the argument in decimal. 

Throws: 
NumberFormatException - if the string does not contain a parsable integer. 

主人,問題tm又來了

public class RuntimeExceptionDemo01{
    public static void main(String args[]){
        String str = "123" ;    // 定義字串,全部由數字組成
        int temp = Integer.parseInt(str) ; // 將字串變為int型別
        System.out.println(temp * temp) ;   // 計算乘方
    }
};

可以看到這個方法,命名使用了throws修飾,需要在方法的呼叫處處理異常,為什麼我們可以直接使用,而沒有去處理異常,也沒有編譯報錯呢?

分析一下,這是為什麼呢?我們先看看這個NumberFormatException,看看它的繼承結構:
這裡寫圖片描述
可以發現,這個NumberFormatException異常是RunnTimeException的子類,

Exception和RunntimeException的區別:
①,Exception在程式中必須進行try-catch處理。
②,RunntimeException可以不使用try-catch處理,但是如果有異常產生,則異常將由jvm進行處理。

在Java的異常處理機制中,如果是Exception異常,則必須進行try-catch處理,如果是RunntimeException則不是必須進行try-catch進行處理的,但是為了保證程式的健康性,在有可能出現異常的地方,其實還是進行異常處理比較好。

8,自定義異常類

其實,只需要繼承Exception就可以自定義一個自己需要的異常類了,當然繼承RunntimeException也是可以的。

class MyException extends Exception{    // 自定義異常類,繼承Exception類
    public MyException(String msg){
        super(msg) ;    // 呼叫Exception類中有一個引數的構造方法,傳遞錯誤資訊
    }
};
public class DefaultException{  
    public static void main(String args[]){
        try{
            throw new MyException("自定義異常。") ;    // 丟擲異常
        }catch(Exception e){
            System.out.println(e) ;
        }
    }
}

這裡寫圖片描述

9,斷言

什麼是斷言?
就是肯定某一個操作的返回結果是正確的,如果程式執行到斷言語句的時候,發現斷言不正確了,返回結果是錯誤的了,則通過斷言檢查肯定,會為使用者提示錯誤的資訊。
斷言的使用格式:
assert boolean 表示式;
assert boolean 表示式:詳細資訊;

public class Test{
    public static void main(String args[]){
        int x[] = {1,2,3} ; // 定義陣列,長度為3
        assert x.length==0 ;    // 此處斷言陣列的長度為0
    }
};

這裡寫圖片描述
斷言本身不會影響程式的執行,如果要想要斷言起作用,則必須對斷言進行驗證
enableassertions可以簡寫為ea,

驗證:
這裡寫圖片描述
發現驗證斷言驗證失敗了。
如果斷言驗證是成功的,
這裡寫圖片描述
斷言,也可以自己設定錯誤資訊:

public class Test{
    public static void main(String args[]){
        int x[] = {1,2,3} ; // 定義陣列,長度為3
        assert x.length==0 : "陣列長度不為0" ;    // 此處斷言陣列的長度為0
    }
};

再進行斷言的驗證:
這裡寫圖片描述

1,在實際開發中,斷言用的並不多。
2,throw是丟擲異常;
3,throws是方法宣告出使用,表示此方法不處理異常,而是在方法呼叫處處理此異常;
4,Exception異常是必須處理的,RunntimeException異常不是必須進行處理的,但是為了保證程式的正常執行,最好有異常產生就對其進行處理。
5,如果需要自定義異常,則只需要直接繼承Exception或者RunntimeException即可。

相關推薦

Java異常捕獲處理---總結

一:異常的基本概念 二:異常的基本處理格式 三:異常的繼承結構 四:Java的異常處理機制 五:throws和throw關鍵字的作用 六:Exception和RunntimeException的區別 七:自定義異常類 八

java異常捕獲處理

一、處理異常 try{ //有可能出異常的語句 } [catch (異常型別 物件) { //異常處理 } catch (異常型別 物件) { //異常處理 } catch (異常型別 物件) { //異常處理 }...] [finally { //不管

SpringBoot全域性異常捕獲處理(包括自定義異常捕獲處理

在做專案的時候需要對自定義異常做捕獲和處理,現在將程式碼記錄下來便於以後查閱。 1、全域性異常捕捉處理 @ControllerAdvice( annotations = {RestController.class} ) public class ExceptionHandlerAdv

Java異常型別處理

1.所有的異常都是從Throwable繼承而來的,是所有異常的共同祖先。 2.Throwable有兩個子類,Error和Exception。其中Error是錯誤,對於所有的編譯時期的錯誤以及系統錯誤都是通過Error丟擲的。這些錯誤表示故障發生於虛擬機器自身、或者發生在虛擬機器試圖執行

Java 異常分類處理機制

 1. 引子        try…catch…finally恐怕是大家再熟悉不過的語句了,而且感覺用起來也是很簡單,邏輯上似乎也是很容易理解。不過,我親自體驗的“教訓”告訴我,這個東西可不是想象中的那麼簡單、聽話。不信?那你看看下面的程式碼,“猜猜”它執行後的結果會是什麼?

Python(4)--異常捕獲處理

異常 異常即非正常狀態,在Python中使用異常物件來表示異常。若程式在編譯或執行過程中發生錯誤,程式的執行過程就會發生改變,丟擲異常物件,程式流進入異常處理。如果異常物件沒有被處理或捕捉,程式就會執

異常捕獲處理機制

異常exception 中斷程式 處理異常==排錯 1:搜尋ArithmeticException    非受檢unchecked  編譯時沒有錯 2:大量輸出語句驗證   縮小程式碼範圍,尋找錯誤點 3:會用註釋 不斷找到對的程式碼,進而發現錯誤的程式碼段 4:

Mysql高手系列 - 第20篇:異常捕獲處理詳解(實戰經驗)

Mysql系列的目標是:通過這個系列從入門到全面掌握一個高階開發所需要的全部技能。 這是Mysql系列第20篇。 環境:mysql5.7.25,cmd命令中進行演示。 程式碼中被[]包含的表示可選,|符號分開的表示可選其一。 需求背景 我們在寫儲存過程的時候,可能會出現下列一些情況: 插入的資料違反唯一約束

菜雞的Java筆記 第三十 異常捕獲處理

異常的捕獲及處理        1.異常的產生分析以及所帶來的影響        2.異常的處理的基本格式        3.異常

java異常捕獲處理

異常的捕獲及處理 1.try……catch…… 2.throws 3.throw 4.assert 斷言 First、什麼是異常? 異常是導致一個程式中斷的指令流,一旦出現之後程式就將立即退出。 public class ExpTest{ pu

Java EE專案中異常設計處理總結

異常,為我們處理非正常的業務流程提供了很好的解決方案,如果你有過dbase、c、pascal等過程式語言開發的經歷,你一定會深刻體會到,異常機制給你的程式碼可讀行、可維護性帶來的好處,同時,程式的健壯性也得到了增強。 在 java專案中,異常設計要注意下面的幾點。 一、自定義異常父類的選擇 A、自定義異常的

Java異常捕獲處理(throws關鍵字)

·throws關鍵字主要用於方法宣告上,指的是當前方法之中異常後交給被呼叫處處理;範例1:class MyMath { public static int div(int x, int y) thro

Java 異常捕獲處理(異常處理流程)

import java.util.Scanner; public class Demo { public static void main(String[] args) { Scanner in

異常捕獲處理

height 自定義異常 basic 數字 ... 返回值 如果 pack java 作者:gqk:   1、 異常的產生原因及處理格式   2、 異常的標準使用方式   3、 throw 和 throws 關鍵字的作用 認識異常:保證程序不會因出現異常而終止,必須對有可

JEECG&JWT異常捕獲強化處理 | Java: Meaning of catch (final SomeException e)?

//從header中得到token String authHeader = request.getHeader(JwtConstants.AUTHORIZATION); if (authHeader == null) { th

Java異常捕獲處理機制

在Java中,異常情況分為Exception(異常)和Error(錯誤)兩大類,Java異常通常是指程式執行過程中出現的非正常情況,如使用者輸入錯誤、除數為零、需要處理的檔案不存在、陣列下標越界等,對於異常情況的出現,可以採用異常處理,以保證程式可以正常的執行。 Java中定義兩種型別的異常和錯

Java 異常分類統一處理(一)

一、異常分類 java異常分為”檢查”和”非檢查”兩類,”檢查”二字的意思是,程式碼編譯時,編譯器會去Check一下有沒有進行異常處理(捕獲或向上拋),對於歸類為需要檢查的異常,若沒處理,編譯就過不去。 初學的時候,常常想為啥異常要這樣分類處理? 後來明白了些,異常不過兩種:主觀和客觀,一個大多

Java學習筆記05--強制型別轉換 ;內部類(瞭解即可) ;Java異常體系異常處理;iOS中的try catch 塊

===============java相關講解============= 強制型別轉換: 基本資料型別的轉換 小資料型別---->大的資料型別 自動型別轉換 大資料型別----->小資料型別 強制型別轉換

Java異常機制異常處理建議

1、Java異常機制        異常指不期而至的各種狀況,如:檔案找不到、網路連線失敗、非法引數等。異常是一個事件,它發生在程式執行期間,干擾了正常的指令流程。Java通過API中Throwable類的眾多子

Java 異常分類統一處理

一、異常分類 java異常分為”檢查”和”非檢查”兩類,”檢查”二字的意思是,程式碼編譯時,編譯器會去Check一下有沒有進行異常處理(捕獲或向上拋),對於歸類為需要檢查的異常,若沒處理,編譯就過不去。 初學的時候,常常想為啥異常要這樣分類處理? 後來明白了