偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

聊聊Java中的異常及處理

開(kāi)發(fā) 后端
在編程中異常報(bào)錯(cuò)是不可避免的。特別是在學(xué)習(xí)某個(gè)語(yǔ)言初期,看到異常報(bào)錯(cuò)就抓耳撓腮,常常開(kāi)玩笑說(shuō)編程1分鐘,改bug1小時(shí)。今天就讓我們來(lái)看看什么是異常和怎么合理的處理異常吧!

在編程中異常報(bào)錯(cuò)是不可避免的。特別是在學(xué)習(xí)某個(gè)語(yǔ)言初期,看到異常報(bào)錯(cuò)就抓耳撓腮,常常開(kāi)玩笑說(shuō)編程1分鐘,改bug1小時(shí)。今天就讓我們來(lái)看看什么是異常和怎么合理的處理異常吧!

[[332138]]

異常與error介紹

下面還是先讓我們來(lái)看一下基本概念吧!

​ 異常指程序運(yùn)行過(guò)程中出現(xiàn)的非正常現(xiàn)象,例如用戶輸入錯(cuò)誤、除數(shù)為零、需要處理的文件不存在、數(shù)組下標(biāo)越界等。異常機(jī)制本質(zhì)就是當(dāng)程序出現(xiàn)錯(cuò)誤,程序安全退出的機(jī)制。在Java的異常處理機(jī)制中,引進(jìn)了很多用來(lái)描述和處理異常的類,稱為異常類。異常類定義中包含了該類異常的信息和對(duì)異常進(jìn)行處理的方法。

​Java是采用面向?qū)ο蟮姆绞絹?lái)處理異常的。處理過(guò)程:

  • 拋出異常:在執(zhí)行一個(gè)方法時(shí),如果發(fā)生異常,則這個(gè)方法生成代表該異常的一個(gè)對(duì)象,停止當(dāng)前執(zhí)行路徑,并把異常對(duì)象提交給JRE。
  • 捕獲異常:JRE得到該異常后,尋找相應(yīng)的代碼來(lái)處理該異常。JRE在方法的調(diào)用棧中查找,從生成異常的方法開(kāi)始回溯,直到找到相應(yīng)的異常處理代碼為止。

讓我們來(lái)看看前面所講到的異常類究竟是個(gè)什么東西!

其實(shí)所有的異常對(duì)象都是派生于Throwable類的一個(gè)實(shí)例。如果內(nèi)置的異常類不能夠滿足需要,還可以創(chuàng)建自己的異常類。所有異常的根類為java.lang.Throwable??纯此募易彘L(zhǎng)什么樣。

聊聊Java中的異常及處理

Throwable類下面主要是兩大門派:Error和Exception。

  • Error是程序無(wú)法處理的錯(cuò)誤,表示運(yùn)行應(yīng)用程序中較嚴(yán)重問(wèn)題,系統(tǒng)JVM已經(jīng)處于不可恢復(fù)的崩潰狀態(tài)中。例如,說(shuō)內(nèi)存溢出和線程死鎖等系統(tǒng)問(wèn)題。
  • Exception是程序本身能夠處理的異常。Exception類是所有異常類的父類,其子類對(duì)應(yīng)了各種各樣可能出現(xiàn)的異常事件。 通常Java的異??煞譃椋篟untimeException 運(yùn)行時(shí)異常CheckedException 已檢查異常下面我們來(lái)研究研究這兩個(gè)異常。

RuntimeException和 CheckedException異同

首先我們先來(lái)看看什么是運(yùn)行時(shí)異常。

這類異常通常是由編程錯(cuò)誤導(dǎo)致的,所以在編寫(xiě)程序時(shí),并不要求必須使用異常處理機(jī)制來(lái)處理這類異常,而是經(jīng)常需要通過(guò)增加“邏輯處理來(lái)避免這些異常”。

比如以下常見(jiàn)的幾種異常:

  • ArithmeticException異常
    1. int b=0
    2. System.out.println(1/b); 
    3. //解決: 
    4.   if(b!=0){ 
    5.      System.out.println(1/b); 
    6.   } 
  • NumberFormatException異常
    1. String str = "1234abcf"
    2. System.out.println(Integer.parseInt(str)); 
    3. //解決:  
    4. Pattern p = Pattern.compile("^\\d+$"); 
    5. Matcher m = p.matcher(str); 
    6. if (m.matches()) { // 如果str匹配代表數(shù)字的正則表達(dá)式,才會(huì)轉(zhuǎn)換 
    7.     System.out.println(Integer.parseInt(str)); 
  • ClassCastException異常
    1. Animal a=new Dog(); 
    2. Cat c=(Cat)a; 
    3. //解決:     
    4. if (a instanceof Cat) { 
    5.     Cat c = (Cat) a; 

這里再補(bǔ)充兩點(diǎn),方便大家更好的理解java異常的機(jī)制和處理過(guò)程。

  • 在方法拋出異常之后,運(yùn)行時(shí)系統(tǒng)將轉(zhuǎn)為尋找合適的異常處理器(exception handler)。潛在的異常處理器是異常發(fā)生時(shí)依次存留在調(diào)用棧中的方法的集合。當(dāng)異常處理器所能處理的異常類型與方法拋出的異常類型相符時(shí),即為合適的異常處理器。
  • 運(yùn)行時(shí)系統(tǒng)從發(fā)生異常的方法開(kāi)始,依次回查調(diào)用棧中的方法,直至找到含有合適異常處理器的方法并執(zhí)行。當(dāng)運(yùn)行時(shí)系統(tǒng)遍歷調(diào)用棧而未找到合適的異常處理器,則運(yùn)行時(shí)系統(tǒng)終止。同時(shí),意味著Java程序的終止。

上面我們講述了什么是運(yùn)行時(shí)異常以及一些處理方式,下面就再來(lái)看看什么是已檢查異常吧!

所有不是RuntimeException的異常,統(tǒng)稱為Checked Exception,又被稱為“已檢查異常”,如IOException、SQLException等以及用戶自定義的Exception異常。 這類異常在編譯時(shí)就必須做出處理, 否則無(wú)法通過(guò)編譯。

通常異常的處理方式有兩種:

  • 使用“try/catch”捕獲異常
  • 使用“throws”聲明異常。

下面就來(lái)詳細(xì)的聊聊吧!

異常的處理

上面已經(jīng)提了,異常處理通常有2種方式。先看看捕獲異常吧。

捕獲異常是通過(guò)3個(gè)關(guān)鍵詞來(lái)實(shí)現(xiàn)的:try-catch-finally。用try來(lái)執(zhí)行一段程序,如果出現(xiàn)異常,系統(tǒng)拋出一個(gè)異常,可以通過(guò)它的類型來(lái)捕捉(catch)并處理它,最后一步是通過(guò)finally語(yǔ)句為異常處理提供一個(gè)統(tǒng)一的出口,finally所指定的代碼都要被執(zhí)行。

這個(gè)捕獲異常其實(shí)也是我們?cè)诿嬖嚨臅r(shí)候會(huì)經(jīng)常碰到的問(wèn)題。下面我們分別再來(lái)對(duì)各個(gè)部分做一個(gè)簡(jiǎn)單的提示吧!

(1) try

一個(gè)try語(yǔ)句必須帶有至少一個(gè)catch語(yǔ)句塊或一個(gè)finally語(yǔ)句塊 。當(dāng)異常處理的代碼執(zhí)行結(jié)束以后,不會(huì)再回到try語(yǔ)句去執(zhí)行尚未執(zhí)行的代碼。

(2) catch

每個(gè)try語(yǔ)句塊可以伴隨一個(gè)或多個(gè)catch語(yǔ)句,用于處理可能產(chǎn)生的不同類型的異常對(duì)象。在此介紹一些常用的方法,這些方法均繼承自Throwable類 。

  • toString ()方法,顯示異常的類名和產(chǎn)生異常的原因。
  • getMessage()方法,只顯示產(chǎn)生異常的原因,但不顯示類名。
  • printStackTrace()方法,用來(lái)跟蹤異常事件發(fā)生時(shí)堆棧的內(nèi)容。

這里有一個(gè)需要特別注意的地方,那就是catch捕獲異常時(shí)的捕獲順序:

如果異常類之間有繼承關(guān)系,在順序安排上就需注意。越是頂層的類,越放在下面,再不然就直接把多余的catch省略掉。 也就是說(shuō)先捕獲子類異常再捕獲父類異常。

(3) finally

finally語(yǔ)句塊中始終都要執(zhí)行,除了遇到了System.exit(0)結(jié)束程序運(yùn)行。針對(duì)這個(gè)特性,所以我們通常在finally中關(guān)閉程序塊已打開(kāi)的資源,比如:關(guān)閉文件流、釋放數(shù)據(jù)庫(kù)連接等。

即使try和catch塊中存在return語(yǔ)句,finally語(yǔ)句也會(huì)執(zhí)行。是在執(zhí)行完finally語(yǔ)句后再通過(guò)return退出。

在這里就有一道非常經(jīng)典的一個(gè)面試題。

  1. public class Test { 
  2.     public static void main(String[]args) { 
  3.        System.out.println(new Test().test());; 
  4.     } 
  5.     static int test(){ 
  6.        int x = 1
  7.        try{ 
  8.           retun x; 
  9.        }finally{ 
  10.           System.out.print("jdbk"+ ++x); 
  11.        } 
  12.     } 
  13. // 問(wèn)輸出結(jié)果? 

先解釋哈這里存在的玄妙吧!

看了上面的講述,我們都知道了當(dāng)try和catch中有return時(shí),finally仍然會(huì)執(zhí)行,所以正常邏輯來(lái)說(shuō)此題的答案應(yīng)該是“jdbk2 2”,但這里存在一個(gè)陷阱,那就是:

finally是在return后面的表達(dá)式運(yùn)算后執(zhí)行的(此時(shí)并沒(méi)有返回運(yùn)算后的值,而是先把要返回的值保 存起來(lái),不管finally中的代碼怎么樣,返回的值都不會(huì)改變,任然是之前保存的值),所以函數(shù)返回值是 在finally執(zhí)行前確定的。因此正確答案應(yīng)該是:“jdbk2 1”。

還有一點(diǎn)需要注意的就是:finally中最好不要包含return,否則程序會(huì)提前退出,返回值不是try或catch中保存的返回值。

接下來(lái)再來(lái)講講聲明異常吧,它相對(duì)來(lái)說(shuō)就比較簡(jiǎn)單了。

在一些情況下,當(dāng)前方法并不需要處理發(fā)生的異常,而是向上傳遞給調(diào)用它的方法處理。如果一個(gè)方法拋出多個(gè)已檢查異常,就必須在方法的首部列出所有的異常,之間以逗號(hào)隔開(kāi)。

  1. public static void readFile(String fileName) throws FileNotFoundException,IOException { 

需要注意的地方就是:

  • 在方法重寫(xiě)中聲明異常時(shí):子類重寫(xiě)父類方法時(shí),如果父類方法有聲明異常,那么子類聲明的異常范圍不能超過(guò)父類聲明的范圍。
  • 聲明異常我們一般在server層中。在controller層或則數(shù)據(jù)訪問(wèn)層一般是捕獲異常。

自定義異常

我們?yōu)槭裁匆远x異常?還不是因?yàn)樵诔绦蛑?,可能?huì)遇到JDK提供的任何標(biāo)準(zhǔn)異常類都無(wú)法充分描述清楚我們想要表達(dá)的問(wèn)題。此時(shí)我們就可以創(chuàng)建自己的異常類,即自定義異常類。

那我們?cè)趺醋远x異常類呢?相信你看了上面的異常類的家族圖應(yīng)該就猜到了。不錯(cuò),自定義異常類只需從Exception類或者它的子類派生一個(gè)子類即可。如果你繼承Exception類,則為受檢查異常,必須對(duì)其進(jìn)行處理;如果不想處理,可以讓自定義異常類繼承運(yùn)行時(shí)異常RuntimeException類。通常我們自定義異常類應(yīng)該包含2個(gè)構(gòu)造器:一個(gè)是默認(rèn)的構(gòu)造器,另一個(gè)是帶有詳細(xì)信息的構(gòu)造器。這里舉一個(gè)例子。

  1. /**IllegalAgeException:非法年齡異常,繼承Exception類*/ 
  2. class IllegalAgeException extends Exception { 
  3.     //默認(rèn)構(gòu)造器 
  4.     public IllegalAgeException() { 
  5.  
  6.     } 
  7.     //帶有詳細(xì)信息的構(gòu)造器,信息存儲(chǔ)在message中 
  8.     public IllegalAgeException(String message) { 
  9.         super(message); 
  10.     } 
  11.  
  12.    public void setAge(int age) throws IllegalAgeException { 
  13.         if (age < 0) { 
  14.             throw new IllegalAgeException("人的年齡不應(yīng)該為負(fù)數(shù)"); 
  15.         } 
  16.         this.age = age; 
  17.     } 

最后給大家講述一點(diǎn)使用異常機(jī)制的建議:

  • 要避免使用異常處理代替錯(cuò)誤處理,這樣會(huì)降低程序的清晰性,并且效率低下。
  • 處理異常不可以代替簡(jiǎn)單測(cè)試---只在異常情況下使用異常機(jī)制。
  • 不要進(jìn)行小粒度的異常處理---應(yīng)該將整個(gè)任務(wù)包裝在一個(gè)try語(yǔ)句塊中。
  • 異常往往在高層處理。

本文授權(quán)轉(zhuǎn)載自公眾號(hào)「良許Linux」。良許,世界500強(qiáng)外企Linux開(kāi)發(fā)工程師,公眾號(hào)里分享大量Linux干貨,歡迎關(guān)注!

 

責(zé)任編輯:趙寧寧 來(lái)源: 今日頭條
相關(guān)推薦

2010-10-09 16:40:52

2013-04-07 10:01:26

Java異常處理

2009-06-25 14:05:40

Java應(yīng)用技巧

2011-07-05 10:20:38

java

2017-06-02 10:25:26

Java異常處理

2012-12-21 10:48:20

Java異常

2017-03-06 16:51:52

Java泛型實(shí)現(xiàn)

2013-04-01 09:39:06

JavaJava異常

2017-09-26 11:43:12

Java異常和處理

2024-10-08 08:00:00

2018-08-20 16:25:48

編程語(yǔ)言Java異常處理

2009-01-05 09:14:17

.NETcatch性能損失

2023-12-11 14:19:00

Java程序異常

2024-02-21 12:18:00

Java虛擬機(jī)JVM

2015-03-16 16:16:15

JavaJava異常處理Java最佳實(shí)踐

2012-11-19 14:29:38

JavaJava異常異常處理

2011-04-06 10:52:51

Java異常處理

2023-10-10 13:23:18

空指針異常Java

2022-04-02 08:14:02

JavaThreadLoca數(shù)據(jù)

2021-12-11 19:00:54

Java中斷機(jī)制
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)