国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Java異常的深入研究與分析

開發(fā) 后端
本文是異常內(nèi)容的集大成者,力求全面,深入的異常知識(shí)研究與分析。本文由金絲燕網(wǎng)獨(dú)家撰寫,參考眾多網(wǎng)上資源,經(jīng)過內(nèi)容辨別取舍,文字格式校驗(yàn)等步驟編輯而成,以饗讀者。對(duì)于本文的內(nèi)容,建議小白需要多多思考力求掌握,對(duì)于老手只需意會(huì)溫故知新。對(duì)于本文的內(nèi)容,屬于基礎(chǔ)知識(shí)研究范疇,切勿以為讀完此文就能將異常知識(shí)掌握到家。

前言

本文是異常內(nèi)容的集大成者,力求全面,深入的異常知識(shí)研究與分析。本文由金絲燕網(wǎng)獨(dú)家撰寫,參考眾多網(wǎng)上資源,經(jīng)過內(nèi)容辨別取舍,文字格式校驗(yàn)等步驟編輯而成,以饗讀者。對(duì)于本文的內(nèi)容,建議小白需要多多思考力求掌握,對(duì)于老手只需意會(huì)溫故知新。對(duì)于本文的內(nèi)容,屬于基礎(chǔ)知識(shí)研究范疇,切勿以為讀完此文就能將異常知識(shí)掌握到家。切記:操千曲而后曉聲,觀千劍而后識(shí)器,所以我覺得沒有大量的源碼閱讀經(jīng)驗(yàn),你很難知道什么時(shí)候需要自定義異常,什么時(shí)候需要拋出異常。

異常機(jī)制概述

異常機(jī)制是指當(dāng)程序出現(xiàn)錯(cuò)誤后,程序如何處理。具體來說,異常機(jī)制提供了程序退出的安全通道。當(dāng)出現(xiàn)錯(cuò)誤后,程序執(zhí)行的流程發(fā)生改變,程序的控制權(quán)轉(zhuǎn)移到異常處理器。

異常處理的流程

當(dāng)程序中拋出一個(gè)異常后,程序從程序中導(dǎo)致異常的代碼處跳出,java虛擬機(jī)檢測(cè)尋找和try關(guān)鍵字匹配的處理該異常的catch塊,如果找到,將控制權(quán)交到catch塊中的代碼,然后繼續(xù)往下執(zhí)行程序,try塊中發(fā)生異常的代碼不會(huì)被重新執(zhí)行。如果沒有找到處理該異常的catch塊,在所有的finally塊代碼被執(zhí)行和當(dāng)前線程的所屬的ThreadGroup的uncaughtException方法被調(diào)用后,遇到異常的當(dāng)前線程被中止。

異常的結(jié)構(gòu)

異常的繼承結(jié)構(gòu):Throwable為基類,Error和Exception繼承Throwable,RuntimeException和IOException等繼承Exception。Error和RuntimeException及其子類成為未檢查異常(unchecked),其它異常成為已檢查異常(checked)。

 

Error異常

Error表示程序在運(yùn)行期間出現(xiàn)了十分嚴(yán)重、不可恢復(fù)的錯(cuò)誤,在這種情況下應(yīng)用程序只能中止運(yùn)行,例如JAVA 虛擬機(jī)出現(xiàn)錯(cuò)誤。Error是一種unchecked Exception,編譯器不會(huì)檢查Error是否被處理,在程序中不用捕獲Error類型的異常。一般情況下,在程序中也不應(yīng)該拋出Error類型的異常。

RuntimeException異常

Exception異常包括RuntimeException異常和其他非RuntimeException的異常。RuntimeException 是一種Unchecked Exception,即表示編譯器不會(huì)檢查程序是否對(duì)RuntimeException作了處理,在程序中不必捕獲RuntimException類型的異常,也不必在方法體聲明拋出RuntimeException類。RuntimeException發(fā)生的時(shí)候,表示程序中出現(xiàn)了編程錯(cuò)誤,所以應(yīng)該找出錯(cuò)誤修改程序,而不是去捕獲RuntimeException。

Checked Exception異常

Checked Exception異常,這也是在編程中使用最多的Exception,所有繼承自Exception并且不是RuntimeException的異常都是checked Exception,上圖中的IOException和ClassNotFoundException。JAVA 語(yǔ)言規(guī)定必須對(duì)checked Exception作處理,編譯器會(huì)對(duì)此作檢查,要么在方法體中聲明拋出checked Exception,要么使用catch語(yǔ)句捕獲checked Exception進(jìn)行處理,不然不能通過編譯。

在聲明方法時(shí)候拋出異常

語(yǔ)法:throws(略)

為什么要在聲明方法拋出異常?

方法是否拋出異常與方法返回值的類型一樣重要。假設(shè)方法拋出異常卻沒有聲明該方法將拋出異常,那么客戶程序員可以調(diào)用這個(gè)方法而且不用編寫處理異常的代碼。那么,一旦出現(xiàn)異常,那么這個(gè)異常就沒有合適的異常控制器來解決。

為什么拋出的異常一定是已檢查異常?RuntimeException與Error可以在任何代碼中產(chǎn)生,它們不需要由程序員顯示的拋出,一旦出現(xiàn)錯(cuò)誤,那么相應(yīng)的異常會(huì)被自動(dòng)拋出。遇到Error,程序員一般是無能為力的;遇到RuntimeException,那么一定是程序存在邏輯錯(cuò)誤,要對(duì)程序進(jìn)行修改;只有已檢查異常才是程序員所關(guān)心的,程序應(yīng)該且僅應(yīng)該拋出或處理已檢查異常。而已檢查異常是由程序員拋出的,這分為兩種情況:客戶程序員調(diào)用會(huì)拋出異常的庫(kù)函數(shù);客戶程序員自己使用throw語(yǔ)句拋出異常。

注意:覆蓋父類某方法的子類方法不能拋出比父類方法更多的異常,所以,有時(shí)設(shè)計(jì)父類的方法時(shí)會(huì)聲明拋出異常,但實(shí)際的實(shí)現(xiàn)方法的代碼卻并不拋出異常,這樣做的目的就是為了方便子類方法覆蓋父類方法時(shí)可以拋出異常。

在方法中如何拋出異常

語(yǔ)法:throw(略)拋出什么異常?

對(duì)于一個(gè)異常對(duì)象,真正有用的信息是異常的對(duì)象類型,而異常對(duì)象本身毫無意義。比如一個(gè)異常對(duì)象的類型是ClassCastException,那么這個(gè)類名就是唯一有用的信息。所以,在選擇拋出什么異常時(shí),最關(guān)鍵的就是選擇異常的類名能夠明確說明異常情況的類。

異常對(duì)象通常有兩種構(gòu)造函數(shù):一種是無參數(shù)的構(gòu)造函數(shù);另一種是帶一個(gè)字符串的構(gòu)造函數(shù),這個(gè)字符串將作為這個(gè)異常對(duì)象除了類型名以外的額外說明。

為什么要?jiǎng)?chuàng)建自己的異常?

當(dāng)Java內(nèi)置的異常都不能明確的說明異常情況的時(shí)候,需要?jiǎng)?chuàng)建自己的異常。需要注意的是,唯一有用的就是類型名這個(gè)信息,所以不要在異常類的設(shè)計(jì)上花費(fèi)精力。

throw和throws的區(qū)別

  1. public class TestThrow 
  2.  
  3.     public static void main(String[] args) 
  4.     { 
  5.         try 
  6.         { 
  7.             //調(diào)用帶throws聲明的方法,必須顯式捕獲該異常 
  8.             //否則,必須在main方法中再次聲明拋出 
  9.             throwChecked(-3);             
  10.         } 
  11.         catch (Exception e) 
  12.         { 
  13.             System.out.println(e.getMessage()); 
  14.         } 
  15.         //調(diào)用拋出Runtime異常的方法既可以顯式捕獲該異常, 
  16.         //也可不理會(huì)該異常 
  17.         throwRuntime(3); 
  18.     } 
  19.     public static void throwChecked(int a)throws Exception 
  20.     { 
  21.         if (a > 0) 
  22.         { 
  23.             //自行拋出Exception異常 
  24.             //該代碼必須處于try塊里,或處于帶throws聲明的方法中 
  25.             throw new Exception("a的值大于0,不符合要求"); 
  26.         } 
  27.     } 
  28.     public static void throwRuntime(int a) 
  29.     { 
  30.         if (a > 0) 
  31.         { 
  32.             //自行拋出RuntimeException異常,既可以顯式捕獲該異常 
  33.             //也可完全不理會(huì)該異常,把該異常交給該方法調(diào)用者處理 
  34.             throw new RuntimeException("a的值大于0,不符合要求"); 
  35.         } 
  36.     } 
  37.  

補(bǔ)充:throwChecked函數(shù)的另外一種寫法如下所示:

  1. public static void throwChecked(int a) 
  2.     { 
  3.         if (a > 0) 
  4.         { 
  5.             //自行拋出Exception異常 
  6.             //該代碼必須處于try塊里,或處于帶throws聲明的方法中 
  7.             try 
  8.             { 
  9.                 throw new Exception("a的值大于0,不符合要求"); 
  10.             } 
  11.             catch (Exception e) 
  12.             { 
  13.                 // TODO Auto-generated catch block 
  14.                 e.printStackTrace(); 
  15.             } 
  16.         } 
  17.     }  

注意:此時(shí)在main函數(shù)里面throwChecked就不用try異常了。

應(yīng)該在聲明方法拋出異常還是在方法中捕獲異常?

處理原則:捕捉并處理哪些知道如何處理的異常,而傳遞哪些不知道如何處理的異常

使用finally塊釋放資源

finally關(guān)鍵字保證無論程序使用任何方式離開try塊,finally中的語(yǔ)句都會(huì)被執(zhí)行。在以下三種情況下會(huì)進(jìn)入finally塊:

(1) try塊中的代碼正常執(zhí)行完畢。

(2) 在try塊中拋出異常。

(3) 在try塊中執(zhí)行return、break、continue。

因此,當(dāng)你需要一個(gè)地方來執(zhí)行在任何情況下都必須執(zhí)行的代碼時(shí),就可以將這些代碼放入finally塊中。當(dāng)你的程序中使用了外界資源,如數(shù)據(jù)庫(kù)連接,文件等,必須將釋放這些資源的代碼寫入finally塊中。

必須注意的是:在finally塊中不能拋出異常。JAVA異常處理機(jī)制保證無論在任何情況下必須先執(zhí)行finally塊然后再離開try塊,因此在try塊中發(fā)生異常的時(shí)候,JAVA虛擬機(jī)先轉(zhuǎn)到finally塊執(zhí)行finally塊中的代碼,finally塊執(zhí)行完畢后,再向外拋出異常。如果在finally塊中拋出異常,try塊捕捉的異常就不能拋出,外部捕捉到的異常就是finally塊中的異常信息,而try塊中發(fā)生的真正的異常堆棧信息則丟失了。請(qǐng)看下面的代碼:

  1. Connection  con = null
  2. try 
  3.     con = dataSource.getConnection(); 
  4.     …… 
  5. catch(SQLException e) 
  6.     …… 
  7.     throw e;//進(jìn)行一些處理后再將數(shù)據(jù)庫(kù)異常拋出給調(diào)用者處理 
  8. finally 
  9.     try 
  10.     { 
  11.         con.close(); 
  12.     } 
  13.     catch(SQLException e) 
  14.     e.printStackTrace(); 
  15.     …… 
  16.  

運(yùn)行程序后,調(diào)用者得到的信息如下

java.lang.NullPointerException

at myPackage.MyClass.method1(methodl.java:266)

而不是我們期望得到的數(shù)據(jù)庫(kù)異常。這是因?yàn)檫@里的con是null的關(guān)系,在finally語(yǔ)句中拋出了NullPointerException,在finally塊中增加對(duì)con是否為null的判斷可以避免產(chǎn)生這種情況。

丟失的異常

請(qǐng)看下面的代碼:

  1. public void method2() 
  2. try 
  3.     …… 
  4.     method1();  //method1進(jìn)行了數(shù)據(jù)庫(kù)操作 
  5. catch(SQLException e) 
  6.     …… 
  7.     throw new MyException("發(fā)生了數(shù)據(jù)庫(kù)異常:"+e.getMessage); 
  8. public void method3() 
  9.     try 
  10.     method2(); 
  11. catch(MyException e) 
  12.     e.printStackTrace(); 
  13.     …… 
  14.  

上面method2的代碼中,try塊捕獲method1拋出的數(shù)據(jù)庫(kù)異常SQLException后,拋出了新的自定義異常MyException。這段代碼是否并沒有什么問題,但看一下控制臺(tái)的輸出:

  1. MyException:發(fā)生了數(shù)據(jù)庫(kù)異常:對(duì)象名稱'MyTable' 無效。 
  2.  at MyClass.method2(MyClass.java:232) 
  3.  at MyClass.method3(MyClass.java:255)  

原始異常SQLException的信息丟失了,這里只能看到method2里面定義的MyException的堆棧情況;而method1中發(fā)生的數(shù)據(jù)庫(kù)異常的堆棧則看不到,如何排錯(cuò)呢,只有在method1的代碼行中一行行去尋找數(shù)據(jù)庫(kù)操作語(yǔ)句了。

JDK的開發(fā)者們也意識(shí)到了這個(gè)情況,在JDK1.4.1中,Throwable類增加了兩個(gè)構(gòu)造方法,public Throwable(Throwable cause)和public Throwable(String message,Throwable cause),在構(gòu)造函數(shù)中傳入的原始異常堆棧信息將會(huì)在printStackTrace方法中打印出來。但對(duì)于還在使用JDK1.3的程序員,就只能自己實(shí)現(xiàn)打印原始異常堆棧信息的功能了。實(shí)現(xiàn)過程也很簡(jiǎn)單,只需要在自定義的異常類中增加一個(gè)原始異常字段,在構(gòu)造函數(shù)中傳入原始異常,然后重載printStackTrace方法,首先調(diào)用類中保存的原始異常的printStackTrace方法,然后再調(diào)用super.printStackTrace方法就可以打印出原始異常信息了。可以這樣定義前面代碼中出現(xiàn)的MyException類:

  1. import java.io.PrintStream; 
  2. import java.io.PrintWriter; 
  3. public class MyException extends Exception 
  4.  
  5.     private static final long serialVersionUID = 1L; 
  6.     //原始異常 
  7.     private Throwable cause; 
  8.     //構(gòu)造函數(shù) 
  9.     public MyException(Throwable cause) 
  10.     { 
  11.         this.cause = cause; 
  12.     } 
  13.     public MyException(String s,Throwable cause) 
  14.     { 
  15.         super(s); 
  16.         this.cause = cause; 
  17.     } 
  18.     //重載printStackTrace方法,打印出原始異常堆棧信息 
  19.     public void printStackTrace() 
  20.     { 
  21.         if (cause != null
  22.         { 
  23.             cause.printStackTrace(); 
  24.         } 
  25.         super.printStackTrace(); 
  26.     } 
  27.  
  28.     public void printStackTrace(PrintStream s) 
  29.     { 
  30.         if (cause != null
  31.         { 
  32.             cause.printStackTrace(s); 
  33.         } 
  34.         super.printStackTrace(s); 
  35.     } 
  36.  
  37.     public void printStackTrace(PrintWriter s) 
  38.     { 
  39.         if (cause != null
  40.         { 
  41.             cause.printStackTrace(s); 
  42.         } 
  43.         super.printStackTrace(s); 
  44.     } 
  45.  
責(zé)任編輯:龐桂玉 來源: Android開發(fā)中文站
相關(guān)推薦

2016-01-12 18:04:55

Java異常研究

2011-12-15 10:43:20

JavaNIO

2011-06-01 10:58:54

Android Service

2022-05-11 09:03:05

CSS容器文本換行

2010-06-21 13:07:14

2010-05-31 17:45:50

MySQL行鎖

2010-11-23 16:35:59

MySQL刪除多表數(shù)據(jù)

2018-12-24 15:00:58

混合云多云云采用

2015-05-13 09:57:14

C++靜態(tài)庫(kù)與動(dòng)態(tài)庫(kù)

2023-11-03 08:25:28

數(shù)據(jù)結(jié)構(gòu)Java

2010-11-18 17:24:27

Oracle旋轉(zhuǎn)ins

2013-01-07 13:38:56

Android開發(fā)布局長(zhǎng)度單位

2009-12-08 18:45:17

PHP檢查函數(shù)可用

2021-05-25 09:00:00

Kubernetes容器集群

2012-01-18 11:24:18

Java

2010-05-19 14:45:46

2009-10-20 10:17:50

綜合布線系統(tǒng)驗(yàn)收

2022-04-19 08:28:34

main函數(shù)

2010-11-26 11:57:35

MySQL結(jié)果字符串

2010-06-19 14:03:20

點(diǎn)贊
收藏

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

av影片在线一区| 亚洲精品成人a在线观看| 久久69成人| 一本一道dvd在线观看免费视频| 欧美精品与人动性物交免费看| 亚洲色图色老头| 日韩欧美aaa| 国产精品久久久久天堂| 丁香婷婷综合五月| 人人狠狠综合久久亚洲| 亚洲v天堂v手机在线| 粉嫩一区二区三区在线观看| 蜜桃视频动漫在线播放| 国产玉足榨精视频在线观看| www.1024| 国产无套粉嫩白浆在线2022年| 欧美影视一区| 激情亚洲色图| 国产日韩中文在线| 欧美三级日韩三级| 奇米精品一区二区三区四区 | 久久精品九色| 免费成年网站| 豆国产97在线| 日韩电影中文字幕在线观看| 26uuu欧美| 久久不见久久见国语| h视频在线观看免费| 国产成人免费高清视频| 久久久久久成人精品| 国产福利不卡视频| 91国语精品自产拍在线观看性色 | 爆操妹子视频在线观看| 91精品国产99久久久久久红楼| 欧美性猛交视频| 日韩一卡二卡三卡国产欧美| 一本色道久久综合狠狠躁的番外| 在线看片你懂得| 午夜精品美女久久久久av福利| 精品国产欧美成人夜夜嗨| 亚洲成人av资源| 麻豆精品精品国产自在97香蕉| 国产+成+人+亚洲欧洲在线| 粉嫩av一区| 丁香六月激情婷婷| 国产日韩精品电影| 亚洲午夜女主播在线直播| 亚洲一二三专区| 黄页视频在线91| 欧美中文一区二区| 日韩伦理在线| 成视频在线免费观看| 一区二区三区四区视频在线观看| 91精品国产91| 日韩女优电影在线观看| 国产精品第四页| 美女高潮久久久| 欧美日韩一二三四| 日韩成人高清| 三级国产在线观看| 波多野结衣50连登视频| 国内精品视频在线播放| 欧美激情亚洲一区| 精品粉嫩超白一线天av| 一二三区精品视频| 国产精品一二二区| 91精品天堂福利在线观看| 91视频成人| 日韩成人伦理| 青娱在线视频| 波多野结衣50连登视频| 日本一区二区在线视频| 国产伦精品一区二区三区精品视频| 亚洲色图av在线| 欧美老人xxxx18| 一区二区在线免费观看| 成人黄色777网| 先锋影音国产一区| 99精品视频在线观看播放| 国产三线在线| 精品视频一二区| 国产女优裸体网站| aa在线免费观看| 亚洲不卡1区| 国产精品二区在线| 欧美亚洲激情在线| 色吧影院999| 精品剧情v国产在线观看在线| 亚洲成av人片在www色猫咪| 国产欧美日韩亚州综合| 国产综合成人久久大片91| 国产美女一区| 五月婷婷六月综合| 亚洲人挤奶视频| 99热这里有精品| 欧洲一区精品| www.久久ai| 在线a免费看| 色吊丝在线永久观看最新版本| 羞羞在线观看网站| 99精品视频在线看| 妺妺窝人体色www看人体| 亚洲国产一区二区三区在线| 国产视频一区二区不卡| 国产精品中文字幕在线观看| 午夜精品在线视频| 久久av在线播放| 色阁综合伊人av| 国产亚洲欧美aaaa| 亚洲福利视频网| 日韩一区二区三区电影在线观看| 欧美性色欧美a在线播放| 精品福利樱桃av导航| 亚洲一区二区在线免费观看视频 | 中文字幕乱码中文乱码51精品| 国产美女福利在线| 中文字幕在线免费| 可以在线观看的av网站| 中文字幕欧美一区二区| 日本调教视频在线观看| av手机免费观看| 男女激情网站| 97在线观看免费高清视频| 天天干狠狠干| 蜜臀一区二区三区| 在线观看av网| 永久免费在线| 暖暖视频在线免费观看| 国产在线超碰| 国产激情视频在线| 日皮视频在线观看| heyzo中文字幕在线| 国产一区二区你懂的| 奇米四色中文综合久久 | av片哪里在线观看| 日韩美女视频免费看| 日韩中文字幕免费| 国产小视频91| 国产一区二区三区在线免费观看| 精品视频久久久| 国产丝袜一区二区三区免费视频| 亚洲国产小视频| 日韩激情片免费| 亚洲人成绝费网站色www| 亚洲天堂偷拍| 欧美精选一区| 在线观看日韩av电影| 好看的亚洲午夜视频在线| 欧美91大片| 黄色国产精品| 国产亚洲精品久久久久婷婷瑜伽| 夜夜精品视频| 日韩av二区在线播放| 另类小说一区二区三区| 激情综合色丁香一区二区| 国产乱码精品一区二区三区av| 国产精品88av| 91丨porny丨最新| 国产精品视频在线看| 一区二区三区中文字幕在线观看| 亚洲成人免费观看| 一本一道久久a久久精品| 欧美日韩大陆在线| 欧美一区二区三区精品| 亚洲福利小视频| 爽爽爽爽爽爽爽成人免费观看| 裸体女人亚洲精品一区| 欧美主播福利视频| 亚洲综合成人婷婷小说| 免费精品视频一区| 特级西西444| 熟妇人妻无乱码中文字幕真矢织江 | 亚洲精品视频自拍| 国产99久久久欧美黑人| 黄色污污视频在线观看| 在线精品高清中文字幕| 在线视频免费一区二区| 欧美高清视频在线| 国产精品视频白浆免费视频| 国产欧美日韩视频一区二区三区| 夜夜爽www精品| 丝袜制服一区二区三区| 欧美精品在线一区二区三区| 日本在线看片免费人成视1000| 蜜臀精品久久久久久蜜臀| 中文字幕精品久久| 在线播放91| av电影一区二区| 日韩精品视频中文字幕| 波多野结衣在线播放一区| 亚洲欧美激情诱惑| aaa国产一区| 午夜激情一区二区| 亚洲黄色www| 欧美在线影院在线视频| 精品欧美日韩| 手机在线看福利| 国产福利在线播放麻豆| 任你弄在线视频免费观看| 久久久视频免费观看|