在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

您好,歡迎來電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊]

您的位置:電子發(fā)燒友網(wǎng)>源碼下載>java源碼下載>

java中處理異常的方式詳解

大小:0.2 MB 人氣: 2017-09-27 需要積分:0

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

  異常機(jī)制概述

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

  異常處理的流程

  當(dāng)程序中拋出一個異常后,程序從程序中導(dǎo)致異常的代碼處跳出,java虛擬機(jī)檢測尋找和try關(guān)鍵字匹配的處理該異常的catch塊,如果找到,將控制權(quán)交到catch塊中的代碼,然后繼續(xù)往下執(zhí)行程序,try塊中發(fā)生異常的代碼不會被重新執(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)。

  java中處理異常的方式詳解

  Error異常

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

  RuntimeException異常

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

  Checked Exception異常

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

  在聲明方法時候拋出異常

  語法:throws(略)

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

  方法是否拋出異常與方法返回值的類型一樣重要。假設(shè)方法拋出異常卻沒有聲明該方法將拋出異常,那么客戶程序員

  可以調(diào)用這個方法而且不用編寫處理異常的代碼。那么,一旦出現(xiàn)異常,那么這個異常就沒有合適的異常控制器來解決。

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

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

  在方法中如何拋出異常

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

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

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

  為什么要創(chuàng)建自己的異常?

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

  throw和throws的區(qū)別 /** * Java學(xué)習(xí)交流QQ群:589809992 我們一起學(xué)Java! */publicclassTestThrow{publicstaticvoidmain(String[] args) { try{ //調(diào)用帶throws聲明的方法,必須顯式捕獲該異常//否則,必須在main方法中再次聲明拋出throwChecked(- 3); }catch(Exception e) { System.out.println(e.getMessage()); } //調(diào)用拋出Runtime異常的方法既可以顯式捕獲該異常,//也可不理會該異常throwRuntime( 3); }publicstaticvoidthrowChecked( inta) throwsException { if(a 》 0) { //自行拋出Exception異常//該代碼必須處于try塊里,或處于帶throws聲明的方法中thrownewException( “a的值大于0,不符合要求”); } } publicstaticvoidthrowRuntime( inta) { if(a 》 0) { //自行拋出RuntimeException異常,既可以顯式捕獲該異常//也可完全不理會該異常,把該異常交給該方法調(diào)用者處理thrownewRuntimeException( “a的值大于0,不符合要求”); } } }

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

  publicstaticvoidthrowChecked( inta) { if(a 》 0) { //自行拋出Exception異常//該代碼必須處于try塊里,或處于帶throws聲明的方法中try{ thrownewException( “a的值大于0,不符合要求”); } catch(Exception e) { // TODO Auto-generated catch blocke.printStackTrace(); } } }

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

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

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

  使用finally塊釋放資源

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

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

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

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

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

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

  Connection con = null; try{ con = dataSource.getConnection(); …… } catch(SQLException e) { …… throwe; //進(jìn)行一些處理后再將數(shù)據(jù)庫異常拋出給調(diào)用者處理} finally{ try{ con.close(); } catch(SQLException e) { e.printStackTrace(); …… } }

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

  java.lang.NullPointerException

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

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

  丟失的異常

  請看下面的代碼:

  publicvoidmethod2() { try{ …… method1(); //method1進(jìn)行了數(shù)據(jù)庫操作}catch(SQLException e) { …… thrownewMyException( “發(fā)生了數(shù)據(jù)庫異常:”+e.getMessage); } } publicvoidmethod3() { try{ method2(); } catch(MyException e) { e.printStackTrace(); …… } }

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

  MyException:發(fā)生了數(shù)據(jù)庫異常:對象名稱 ‘MyTable’ 無效。at MyClass.method2(MyClass.java: 232) at MyClass.method3( MyClass.java: 255)

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

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

  importjava.io.PrintStream; importjava.io.PrintWriter;publicclassMyExceptionextendsException{privatestaticfinallongserialVersionUID = 1L; //原始異常privateThrowable cause; //構(gòu)造函數(shù)publicMyException(Throwable cause) {this.cause = cause; } publicMyException(String s,Throwable cause) { super(s); this.cause = cause; } //重載printStackTrace方法,打印出原始異常堆棧信息publicvoidprintStackTrace() { if(cause != null) { cause.printStackTrace(); }super.printStackTrace(); } publicvoidprintStackTrace(PrintStream s) { if(cause != null) { cause.printStackTrace(s); } super.printStackTrace(s); }publicvoidprintStackTrace(PrintWriter s) { if(cause != null) { cause.printStackTrace(s); }super.printStackTrace(s); } }

非常好我支持^.^

(0) 0%

不好我反對

(0) 0%

      發(fā)表評論

      用戶評論
      評價:好評中評差評

      發(fā)表評論,獲取積分! 請遵守相關(guān)規(guī)定!

      ?
      主站蜘蛛池模板: 欧美一级在线观看视频 | 欧美成年网站 | 色一欲一性一乱一区二区三区 | www.激情五月.com | 35qao强力打造免费上线高清 | 国产二区三区毛片 | 欧美大片国产在线永久播放 | 清朝荒淫牲艳史在线播放 | 最刺激黄a大片免费网站 | 在线看一区二区 | 欧美女人天堂 | 国产青草 | 国产精品一区在线播放 | 又粗又硬又爽又黄毛片 | 嫩草影院在线入口 | 特黄特色大片免费视频播放 | www.黄com| 日本网站免费 | 色姑娘网 | 婷婷丁香在线 | 久久免费视频网站 | 毛片爱爱 | 一级做受毛片免费大片 | 少妇被按摩| 精品色图| 欧美性黑人极品hd网站 | 欧美日本一道免费一区三区 | 国产成人免费无庶挡视频 | 欧美一卡二三卡四卡不卡 | 免费人成在线观看视频播放 | 女人午夜啪啪性刺激免费看 | 午夜性福 | 中文字幕天天躁夜夜狠狠综合 | 日本色视 | 亚洲理论在线 | 六月婷婷网 | 1024你懂的国产精品 | 奇米欧美 | 在线看片成人免费视频 | 日韩一卡 二卡 三卡 四卡 免费视频 | aaa在线观看视频高清视频 |