亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Java中異常Exception和捕獲以及自定義異常詳解

 更新時間:2023年05月17日 16:02:12   作者:魚找水需要時間  
在工作過程中,我們常常需要在合適的地方拋出合適的異常,除了java自帶的一些異常,我們可以在項目中定制自己的異常,并且全局捕獲它,下面這篇文章主要給大家介紹了關于Java中異常Exception和捕獲以及自定義異常的相關資料,需要的朋友可以參考下

1. 異常概述

1.1 什么是程序的異常

在使用計算機語言進行項目開發(fā)的過程中,即使程序員把代碼寫得盡善盡美,在系統(tǒng)的運行過程中仍然會遇到一些問題,因為很多問題不是靠代碼能夠避免的。

異常 :指的是程序在執(zhí)行過程中,出現(xiàn)的非正常情況,如果不處理最終會導致JVM的非正常停止。

異常指的并不是語法錯誤和邏輯錯誤。語法錯了,編譯不通過,不會產(chǎn)生字節(jié)碼文件,根本不能運行。代碼邏輯錯誤,只是沒有得到想要的結(jié)果,例如:求a與b的和,你寫成了a-b。

1.2 異常的拋出機制

Java中把不同的異常用不同的類表示,一旦發(fā)生某種異常,就創(chuàng)建該異常類型的對象,并且拋出(throw)。然后程序員可以捕獲(catch)到這個異常對象,并處理;如果沒有捕獲(catch)這個異常對象,那么這個異常對象將會導致程序終止。

模擬程序會產(chǎn)生一個數(shù)組角標越界異常(ArrayIndexOfBoundsException):

public class ArrayTools {
    // 對給定的數(shù)組通過給定的角標獲取元素。
    public static int getElement(int[] arr, int index) {
        int element = arr[index];
        return element;
    }
}
//測試類
public class ExceptionDemo {
    public static void main(String[] args) {
        int[] arr = { 34, 12, 67 };
        intnum = ArrayTools.getElement(arr, 4)
        System.out.println("num=" + num);
        System.out.println("over");
    }
}

上述程序執(zhí)行過程圖解:

1.3 如何對待異常

對于程序出現(xiàn)的異常,一般有兩種解決方法:一是遇到錯誤就終止程序的運行。另一種方法是程序員在編寫程序時,就充分考慮到各種可能發(fā)生的異常和錯誤,極力預防和避免。實在無法避免的,要編寫相應的代碼進行異常的檢測、以及異常的處理,保證代碼的健壯性。

2. Java異常體系

2.1 Throwable

Throwable中的常用方法:

  • public void printStackTrace():打印異常的詳細信息。

包含了異常的類型、異常的原因、異常出現(xiàn)的位置、在開發(fā)和調(diào)試階段都得使用printStackTrace

  • public String getMessage():獲取發(fā)生異常的原因。

2.2 Error 和 Exception

Throwable可分為兩類:ErrorException。分別對應著java.lang.Errorjava.lang.Exception兩個類。

Error:Java虛擬機無法解決的嚴重問題。如:JVM系統(tǒng)內(nèi)部錯誤、資源耗盡等嚴重情況。一般不編寫針對性的代碼進行處理。

  • 例如:StackOverflowError(棧內(nèi)存溢出)和OutOfMemoryError(堆內(nèi)存溢出,簡稱OOM)。

Exception: 其它因編程錯誤或偶然的外在因素導致的一般性問題,需要使用針對性的代碼進行處理,使程序繼續(xù)運行。否則一旦發(fā)生異常,程序也會掛掉。

  • 空指針訪問
  • 試圖讀取不存在的文件
  • 網(wǎng)絡連接中斷
  • 數(shù)組角標越界

說明:

  • 無論是Error還是Exception,還有很多子類,異常的類型非常豐富。當代碼運行出現(xiàn)異常時,特別是我們不熟悉的異常時,不要緊張,把異常的類名,找到對應API中去了解是什么類型的異常。

2.3 編譯時異常和運行時異常

Java程序的執(zhí)行分為編譯時過程和運行時過程。有的錯誤只有在運行時才會發(fā)生。

根據(jù)異??赡艹霈F(xiàn)的階段,可以將異常分為:

  • 編譯時期異常(即checked異常、受檢異常):在代碼編譯階段,編譯器就能明確警示當前代碼可能發(fā)生(不是一定發(fā)生)xx異常,并明確督促程序員提前編寫處理它的代碼。如果程序員沒有編寫對應的異常處理代碼,則編譯器就會直接判定編譯失敗,從而不能生成字節(jié)碼文件。通常,這類異常的發(fā)生不是由程序員的代碼引起的,或者不是靠加簡單判斷就可以避免的,例如:FileNotFoundException(文件找不到異常)。
  • 運行時期異常(即runtime異常、unchecked異常、非受檢異常):在代碼編譯階段,編譯器完全不做任何檢查,無論該異常是否會發(fā)生,編譯器都不給出任何提示。只有等代碼運行起來并確實發(fā)生了xx異常,它才能被發(fā)現(xiàn)。通常,這類異常是由程序員的代碼編寫不當引起的,只要稍加判斷,或者細心檢查就可以避免。
  • java.lang.RuntimeException:類及它的子類都是運行時異常。比如:ArrayIndexOutOfBoundsException:數(shù)組下標越界異常,ClassCastException類型轉(zhuǎn)換異常。

3. 常見的錯誤和異常

3.1 Error

最常見的就是VirtualMachineError,它有兩個經(jīng)典的子類:StackOverflowError、OutOfMemoryError

@Test
public void test01(){
    //StackOverflowError
    recursion();
}
public void recursion(){ //遞歸方法
    recursion(); 
}
@Test
public void test02(){
    //OutOfMemoryError
    //方式一:
    int[] arr = new int[Integer.MAX_VALUE];
}

3.2 運行時異常

@Test
public void test05(){
    int a = 1;
    int b = 0;
    //ArithmeticException
    System.out.println(a/b);
}

3.3 編譯時異常

@Test
public void test06() {
    Thread.sleep(1000);//休眠1秒  InterruptedException
}

4. 異常的處理

4.1 異常處理概述

在編寫程序時,經(jīng)常要在可能出現(xiàn)錯誤的地方加上檢測的代碼,如進行x/y運算時,要檢測分母為0,數(shù)據(jù)為空,輸入的不是數(shù)據(jù)而是字符等。過多的if-else分支會導致程序的代碼加長、臃腫,可讀性差,程序員需要花很大的精力“堵漏洞”。因此采用異常處理機制。

Java異常處理:

Java采用的異常處理機制,是將異常處理的程序代碼集中在一起,與正常的程序代碼分開,使得程序簡潔、優(yōu)雅,并易于維護。

Java異常處理的方式:

  • 方式一: try-catch-finally
  • 方式二: throws + 異常類型

4.2 捕獲異常(try-catch-finally)

Java提供了異常處理的抓拋模型。

  • Java程序的執(zhí)行過程中如出現(xiàn)異常,會生成一個異常類對象,該異常對象將被提交給Java運行時系統(tǒng),這個過程稱為拋出(throw)異常。
  • 如果一個方法內(nèi)拋出異常,該異常對象會被拋給調(diào)用者方法中處理。如果異常沒有在調(diào)用者方法中處理,它繼續(xù)被拋給這個調(diào)用方法的上層方法。這個過程將一直繼續(xù)下去,直到異常被處理。這一過程稱為捕獲(catch)異常。
  • 如果一個異?;氐絤ain()方法,并且main()也不處理,則程序運行終止。

4.2.1 try-catch-finally基本格式

try{
	......	//可能產(chǎn)生異常的代碼
}
catch( 異常類型1 e ){
	......	//當產(chǎn)生異常類型1型異常時的處置措施
}
catch( 異常類型2 e ){
	...... 	//當產(chǎn)生異常類型2型異常時的處置措施
}  
finally{
	...... //無論是否發(fā)生異常,都無條件執(zhí)行的語句
} 

1、整體執(zhí)行過程:

當某段代碼可能發(fā)生異常,不管這個異常是編譯時異常(受檢異常)還是運行時異常(非受檢異常),我們都可以使用try塊將它括起來,并在try塊下面編寫catch分支嘗試捕獲對應的異常對象。

  • 如果在程序運行時,try塊中的代碼沒有發(fā)生異常,那么catch所有的分支都不執(zhí)行。
  • 如果在程序運行時,try塊中的代碼發(fā)生了異常,根據(jù)異常對象的類型,將從上到下選擇第一個匹配的catch分支執(zhí)行。此時try中發(fā)生異常的語句下面的代碼將不執(zhí)行,而整個try…catch之后的代碼可以繼續(xù)運行。
  • 如果在程序運行時,try塊中的代碼發(fā)生了異常,但是所有catch分支都無法匹配(捕獲)這個異常,那么JVM將會終止當前方法的執(zhí)行,并把異常對象“拋”給調(diào)用者。如果調(diào)用者不處理,程序就掛了。

2、try:

捕獲異常的第一步是用try{…}語句塊選定捕獲異常的范圍,將可能出現(xiàn)異常的業(yè)務邏輯代碼放在try語句塊中。

3、catch (Exceptiontype e)

  • catch分支,分為兩個部分,catch()中編寫異常類型和異常參數(shù)名,{}中編寫如果發(fā)生了這個異常,要做什么處理的代碼。
  • 如果明確知道產(chǎn)生的是何種異常,可以用該異常類作為catch的參數(shù);也可以用其父類作為catch的參數(shù)。
  • 比如:可以用ArithmeticException類作為參數(shù)的地方,就可以用RuntimeException類作為參數(shù),或者用所有異常的父類Exception類作為參數(shù)。但不能是與ArithmeticException類無關的異常,如NullPointerException(catch中的語句將不會執(zhí)行)。
  • 每個try語句塊可以伴隨一個或多個catch語句,用于處理可能產(chǎn)生的不同類型的異常對象。
  • 如果有多個catch分支,并且多個異常類型有父子類關系,必須保證小的子異常類型在上,大的父異常類型在下。否則,報錯。
  • catch中常用異常處理的方式
    • public String getMessage():獲取異常的描述信息,返回字符串
    • public void printStackTrace():打印異常的跟蹤棧信息并輸出到控制臺。包含了異常的類型、異常的原因、還包括異常出現(xiàn)的位置,在開發(fā)和調(diào)試階段,都得使用printStackTrace()。

4.2.2 finally使用及舉例

  • 因為異常會引發(fā)程序跳轉(zhuǎn),從而會導致有些語句執(zhí)行不到。而程序中有一些特定的代碼無論異常是否發(fā)生,都需要執(zhí)行。例如,數(shù)據(jù)庫連接、輸入流輸出流、Socket連接、Lock鎖的關閉等,這樣的代碼通常就會放到finally塊中。所以,我們通常將一定要被執(zhí)行的代碼聲明在finally中。
    • 唯一的例外,使用 System.exit(0) 來終止當前正在運行的 Java 虛擬機。
  • 不論在try代碼塊中是否發(fā)生了異常事件,catch語句是否執(zhí)行,catch語句是否有異常,catch語句中是否有return,finally塊中的語句都會被執(zhí)行。
  • finally語句和catch語句是可選的,但finally不能單獨使用。

4.3 聲明拋出異常類型(throws)

如果在編寫方法體的代碼時,某句代碼可能發(fā)生某個編譯時異常,不處理編譯不通過,但是在當前方法體中可能不適合處理或無法給出合理的處理方式,則此方法應顯示地聲明拋出異常,表明該方法將不對這些異常進行處理,而由該方法的調(diào)用者負責處理。

具體方式: 在方法聲明中用throws語句可以聲明拋出異常的列表,throws后面的異常類型可以是方法中產(chǎn)生的異常類型,也可以是它的父類。

4.3.1 throws基本格式

聲明異常格式:

修飾符 返回值類型 方法名(參數(shù)) throws 異常類名1,異常類名2…{ }

在throws后面可以寫多個異常類型,用逗號隔開。

public void readFile(String file)  throws FileNotFoundException,IOException {
	...
	// 讀文件的操作可能產(chǎn)生FileNotFoundException或IOException類型的異常
	FileInputStream fis = new FileInputStream(file);
    //...
}

throws后面也可以寫運行時異常類型,只是運行時異常類型,寫或不寫對于編譯器和程序執(zhí)行來說都沒有任何區(qū)別。如果寫了,唯一的區(qū)別就是調(diào)用者調(diào)用該方法后,使用try…catch結(jié)構(gòu)時,IDEA可以獲得更多的信息,需要添加哪種catch分支。

4.3.2 方法重寫中throws的要求

方法重寫時:

(1)方法名必須相同

(2)形參列表必須相同

(3)返回值類型

  • 基本數(shù)據(jù)類型和void:必須相同
  • 引用數(shù)據(jù)類型:<=

(4)權(quán)限修飾符:>=,而且要求父類被重寫方法在子類中是可見的

(5)不能是staticfinal修飾的方法

對于throws異常列表要求:

  • 如果父類被重寫方法的方法簽名后面沒有 “throws 編譯時異常類型”,那么重寫方法時,方法簽名后面也不能出現(xiàn)“throws 編譯時異常類型”。
  • 如果父類被重寫方法的方法簽名后面有 “throws 編譯時異常類型”,那么重寫方法時,throws的編譯時異常類型必須 <= 被重寫方法throws的編譯時異常類型,或者不throws編譯時異常。
  • 方法重寫,對于“throws 運行時異常類型”沒有要求。

4.4 兩種異常處理方式的選擇

對于異常,使用相應的處理方式。此時的異常,主要指的是編譯時異常

  • 如果程序代碼中,涉及到資源的調(diào)用(流、數(shù)據(jù)庫連接、網(wǎng)絡連接等),則必須考慮使用try-catch-finally來處理,保證不出現(xiàn)內(nèi)存泄漏。
  • 如果父類被重寫的方法沒有throws異常類型,則子類重寫的方法中如果出現(xiàn)異常,只能考慮使用try-catch-finally進行處理,不能throws。
  • 開發(fā)中,方法a中依次調(diào)用了方法b,c,d等方法,方法b,c,d之間是遞進關系。此時,如果方法b,c,d中有異常,我們通常選擇使用throws,而方法a中通常選擇使用try-catch-finally。

5. 手動拋出異常對象:throw

Java 中異常對象的生成有兩種方式:

  • 由虛擬機自動生成:程序運行過程中,虛擬機檢測到程序發(fā)生了問題,那么針對當前代碼,就會在后臺自動創(chuàng)建一個對應異常類的實例對象并拋出。
  • 由開發(fā)人員手動創(chuàng)建:new 異常類型([實參列表]);,如果創(chuàng)建好的異常對象不拋出對程序沒有任何影響,和創(chuàng)建一個普通對象一樣,但是一旦throw拋出,就會對程序運行產(chǎn)生影響了。

5.1 使用格式

throw new 異常類名(參數(shù));

throw語句拋出的異常對象,和JVM自動創(chuàng)建和拋出的異常對象一樣。

  • 如果是編譯時異常類型的對象,同樣需要使用throws或者try…catch處理,否則編譯不通過。
  • 如果是運行時異常類型的對象,編譯器不提示。
  • 可以拋出的異常必須是Throwable或其子類的實例。

5.2 使用注意點

無論是編譯時異常類型的對象,還是運行時異常類型的對象,如果沒有被try..catch合理的處理,都會導致程序崩潰。

throw語句會導致程序執(zhí)行流程被改變,throw語句是明確拋出一個異常對象,因此它下面的代碼將不會執(zhí)行。

如果當前方法沒有try…catch處理這個異常對象,throw語句就會代替return語句提前終止當前方法的執(zhí)行,并返回一個異常對象給調(diào)用者。

6. 自定義異常

6.1 為什么需要自定義異常類

Java中不同的異常類,分別表示著某一種具體的異常情況。那么在開發(fā)中總是有些異常情況是核心類庫中沒有定義好的,此時我們需要根據(jù)自己業(yè)務的異常情況來定義和業(yè)務相關的異常類。

6.2 如何自定義異常類

(1)要繼承一個異常類型

自定義一個編譯時異常類型:自定義類繼承java.lang.Exception。
自定義一個運行時異常類型:自定義類繼承java.lang.RuntimeException。

(2)建議提供至少兩個構(gòu)造器,一個是無參構(gòu)造,一個是(String message)構(gòu)造器。

(3)自定義異常需要提供serialVersionUID

6.3 注意點

  1. 自定義的異常只能通過throw拋出。
  2. 自定義異常最重要的是異常類的名字和message屬性。當異常出現(xiàn)時,可以根據(jù)名字判斷異常類型。比如:TeamException(“成員已滿,無法添加”);
  3. 自定義異常對象只能手動拋出。拋出后由try…catch處理,也可以甩鍋throws給調(diào)用者處理。

示例:

//自定義異常:
public class NotTriangleException extends Exception{
    static final long serialVersionUID = 13465653435L;
    public NotTriangleException() {
    }
    public NotTriangleException(String message) {
        super(message);
    }
}
//手動拋出異常對象
throw new NotTriangleException("輸入數(shù)據(jù)不正確");

7. 總結(jié)

異常處理5個關鍵字:

總結(jié)

到此這篇關于Java中異常Exception和捕獲以及自定義異常的文章就介紹到這了,更多相關Java異常Exception和捕獲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java下載文件中文文件名亂碼的解決方案(文件名包含很多%)

    Java下載文件中文文件名亂碼的解決方案(文件名包含很多%)

    Java下載文件時,文件名中文亂碼問題通常是由于編碼不正確導致的,使用`URLEncoder.encode(filepath, "UTF-8")`可以解決在提示下載框中正確顯示漢字文件名的問題,但在選擇直接打開時,文件名會變成亂碼,解決這個問題的方法
    2025-02-02
  • Logback日志存放路徑不統(tǒng)一解決方案

    Logback日志存放路徑不統(tǒng)一解決方案

    這篇文章主要介紹了Logback日志存放路徑不統(tǒng)一解決方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-10-10
  • springboot連接kafka集群的使用示例

    springboot連接kafka集群的使用示例

    在項目中使用kafka的場景有很多,尤其是實時產(chǎn)生的數(shù)據(jù)流,本文主要介紹了springboot連接kafka集群的使用示例,具有一定的參考價值,感興趣的可以了解一下
    2023-09-09
  • Java基于Google zxing生成帶logo的二維碼圖片

    Java基于Google zxing生成帶logo的二維碼圖片

    zxing是一個開放源碼的,用java實現(xiàn)的多種格式的1D/2D條碼圖像處理庫,本文主要介紹了Java基于Google zxing生成帶logo的二維碼圖片,具有一定的參考價值,感興趣的可以了解一下
    2023-10-10
  • Java的ArrayList擴容源碼解析

    Java的ArrayList擴容源碼解析

    這篇文章主要介紹了Java的ArrayList擴容源碼解析,通過動態(tài)擴容,ArrayList能夠在添加元素時保持高效的性能,擴容操作是有一定開銷的,但由于擴容的時間復雜度為O(n),其中n是當前元素個數(shù),所以平均情況下,每次添加元素的時間復雜度仍然是O(1),需要的朋友可以參考下
    2024-01-01
  • 移除元素Java實現(xiàn)方式

    移除元素Java實現(xiàn)方式

    這篇文章主要介紹了移除元素Java實現(xiàn)方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-04-04
  • Java?超詳細講解SpringMVC攔截器

    Java?超詳細講解SpringMVC攔截器

    Spring?MVC?的攔截器(Interceptor)與?Java?Servlet?的過濾器(Filter)類似,它主要用于攔截用戶的請求并做相應的處理,通常應用在權(quán)限驗證、記錄請求信息的日志、判斷用戶是否登錄等功能上。本文將代碼演示和文字描述詳解攔截器的使用
    2022-04-04
  • shade解決mybatis包沖突問題及項目引用的方法

    shade解決mybatis包沖突問題及項目引用的方法

    這篇文章主要介紹了shade解決mybatis包沖突問題及項目引用的方法,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-08-08
  • Java基礎之FileInputStream和FileOutputStream流詳解

    Java基礎之FileInputStream和FileOutputStream流詳解

    這篇文章主要介紹了Java基礎之FileInputStream和FileOutputStream流詳解,文中有非常詳細的代碼示例,對正在學習java基礎的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-04-04
  • Java系統(tǒng)中拆分同步和異步詳解

    Java系統(tǒng)中拆分同步和異步詳解

    這篇文章主要給大家介紹了關于Java系統(tǒng)中拆分同步和異步的相關資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Java具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-06-06

最新評論