摘要:不受檢查異常為編譯器不要求強制處理的異常,檢查異常則是編譯器要求必須處置的異常。潛在的異常處理器是異常發(fā)生時依次存留在調(diào)用棧中的方法的集合。當(dāng)運行時系統(tǒng)遍歷調(diào)用棧而未找到合適的異常處理器,則運行時系統(tǒng)終止。異常處理涉及到五個關(guān)鍵字,分別是。
概念
程序運行時,發(fā)生的不被期望的事件,它阻止了程序按照程序員的預(yù)期正常執(zhí)行,這就是異常。
異常是程序中的一些錯誤,但并不是所有的錯誤都是異常,并且錯誤有時候是可以避免的。
比如說,你的代碼少了一個分號,那么運行出來結(jié)果是提示是錯誤java.lang.Error;如果你用System.out.println(11/0),那么你是因為你用0做了除數(shù),會拋出java.lang.ArithmeticException的異常。
異常處理機制能讓程序在異常發(fā)生時,按照代碼的預(yù)先設(shè)定的異常處理邏輯,針對性地處理異常,讓程序盡最大可能恢復(fù)正常并繼續(xù)執(zhí)行,且保持代碼的清晰。
Java中的異常可以是函數(shù)中的語句執(zhí)行時引發(fā)的,也可以是程序員通過throw 語句手動拋出的,只要在Java程序中產(chǎn)生了異常,就會用一個對應(yīng)類型的異常對象來封裝異常,JRE就會試圖尋找異常處理程序來處理異常。
異常的體系結(jié)構(gòu)Java把異常當(dāng)作對象來處理,并定義一個基類java.lang.Throwable作為所有異常的超類。
在Java API中已經(jīng)定義了許多異常類,這些異常類分為兩大類,錯誤Error和異常Exception。
java異常層次結(jié)構(gòu)圖:
總從圖中可以看出所有異常類型都是內(nèi)置類Throwable的子類,因而Throwable在異常類的層次結(jié)構(gòu)的頂層。
接下來Throwable分成了兩個不同的分支,一個分支是Error,它表示不希望被程序捕獲或者是程序無法處理的錯誤。另一個分支是Exception,它表示用戶程序可能捕捉的異常情況或者說是程序可以處理的異常。其中異常類Exception又分為運行時異常(RuntimeException)和非運行時異常。
Java異常又可以分為非檢查異常(Unchecked Exception)和檢查異常(Checked Exception)。
下面將詳細講述這些異常之間的區(qū)別與聯(lián)系:
Error:Error類對象由 Java 虛擬機生成并拋出,大多數(shù)錯誤與代碼編寫者所執(zhí)行的操作無關(guān)。例如,Java虛擬機運行錯誤(Virtual MachineError),當(dāng)JVM不再有繼續(xù)執(zhí)行操作所需的內(nèi)存資源時,將出現(xiàn)?OutOfMemoryError。這些異常發(fā)生時,Java虛擬機(JVM)一般會選擇線程終止;還有發(fā)生在虛擬機試圖執(zhí)行應(yīng)用時,如類定義錯誤(NoClassDefFoundError)、鏈接錯誤(LinkageError)。這些錯誤是不可查的,因為它們在應(yīng)用程序的控制和處理能力之外,而且絕大多數(shù)是程序運行時不允許出現(xiàn)的狀況。對于設(shè)計合理的應(yīng)用程序來說,即使確實發(fā)生了錯誤,本質(zhì)上也不應(yīng)該試圖去處理它所引起的異常狀況。在Java中,錯誤通常是使用Error的子類描述。
Exception:在Exception分支中有一個重要的子類RuntimeException(運行時異常),該類型的異常自動為你所編寫的程序定義ArrayIndexOutOfBoundsException(數(shù)組下標(biāo)越界)、NullPointerException(空指針異常)、ArithmeticException(算術(shù)異常)、MissingResourceException(丟失資源)、ClassNotFoundException(找不到類)等異常,這些異常是不檢查異常,程序中可以選擇捕獲處理,也可以不處理。這些異常一般是由程序邏輯錯誤引起的,程序應(yīng)該從邏輯角度盡可能避免這類異常的發(fā)生;而RuntimeException之外的異常我們統(tǒng)稱為非運行時異常,類型上屬于Exception類及其子類,從程序語法角度講是必須進行處理的異常,如果不處理,程序就不能編譯通過。如IOException、SQLException等以及用戶自定義的Exception異常,一般情況下不自定義檢查異常。
Error和Exception的區(qū)別Error通常是災(zāi)難性的致命的錯誤,是程序無法控制和處理的,當(dāng)出現(xiàn)這些異常時,Java虛擬機(JVM)一般會選擇終止線程;Exception通常情況下是可以被程序處理的,并且在程序中應(yīng)該盡可能的去處理這些異常。
檢測異常和不受檢查異常不受檢查異常:包括RuntimeException及其子類和Error。
檢查異常:在正確的程序運行過程中,很容易出現(xiàn)的、情理可容的異常狀況,在一定程度上這種異常的發(fā)生是可以預(yù)測的,并且一旦發(fā)生該種異常,就必須采取某種方式進行處理。除了RuntimeException及其子類以外,其他的Exception類及其子類都屬于檢查異常,當(dāng)程序中可能出現(xiàn)這類異常,要么使用try-catch語句進行捕獲,要么用throws子句拋出,否則編譯無法通過。
不受檢查異常為編譯器不要求強制處理的異常,檢查異常則是編譯器要求必須處置的異常。
異常的處理Java的異常處理本質(zhì)上是拋出異常和捕獲異常
拋出異常:要理解拋出異常,首先要明白什么是異常情形(exception condition),它是指阻止當(dāng)前方法或作用域繼續(xù)執(zhí)行的問題。其次把異常情形和普通問題相區(qū)分,普通問題是指在當(dāng)前環(huán)境下能得到足夠的信息,總能處理這個錯誤。對于異常情形,已經(jīng)無法繼續(xù)下去了,因為在當(dāng)前環(huán)境下無法獲得必要的信息來解決問題,你所能做的就是從當(dāng)前環(huán)境中跳出,并把問題提交給上一級環(huán)境,這就是拋出異常時所發(fā)生的事情。拋出異常后,會有幾件事隨之發(fā)生。首先,是像創(chuàng)建普通的java對象一樣將使用new在堆上創(chuàng)建一個異常對象;然后,當(dāng)前的執(zhí)行路徑(已經(jīng)無法繼續(xù)下去了)被終止,并且從當(dāng)前環(huán)境中彈出對異常對象的引用。此時,異常處理機制接管程序,并開始尋找一個恰當(dāng)?shù)牡胤嚼^續(xù)執(zhí)行程序,這個恰當(dāng)?shù)牡胤骄褪钱惓L幚沓绦蚧蛘弋惓L幚砥鳎娜蝿?wù)是將程序從錯誤狀態(tài)中恢復(fù),以使程序要么換一種方式運行,要么繼續(xù)運行下去。
捕獲異常:在方法拋出異常之后,運行時系統(tǒng)將轉(zhuǎn)為尋找合適的異常處理器(exception handler)。潛在的異常處理器是異常發(fā)生時依次存留在調(diào)用棧中的方法的集合。當(dāng)異常處理器所能處理的異常類型與方法拋出的異常類型相符時,即為合適的異常處理器。運行時系統(tǒng)從發(fā)生異常的方法開始,依次回查調(diào)用棧中的方法,直至找到含有合適異常處理器的方法并執(zhí)行。當(dāng)運行時系統(tǒng)遍歷調(diào)用棧而未找到合適的異常處理器,則運行時系統(tǒng)終止。同時,意味著Java程序的終止。
注意:對于運行時異常、錯誤和檢查異常,Java技術(shù)所要求的異常處理方式有所不同。 對于方法運行中可能出現(xiàn)的Error,當(dāng)運行方法不欲捕捉時,Java允許該方法不做任何拋出聲明。因為,大多數(shù)Error異常屬于永遠不能被允許發(fā)生的狀況,也屬于合理的應(yīng)用程序不該捕捉的異常。 由于運行時異常及其子類的不可查性,為了更合理、更容易地實現(xiàn)應(yīng)用程序,Java規(guī)定,運行時異常將由Java運行時系統(tǒng)自動拋出,允許應(yīng)用程序忽略運行時異常。 對于所有的檢查異常,Java規(guī)定:一個方法必須捕捉,或者聲明拋出方法之外。也就是說,當(dāng)一個方法選擇不捕捉檢查異常時,它必須聲明將拋出異常。
java異常處理涉及到五個關(guān)鍵字,分別是:try、catch、finally、throw、throws。
try?? ?-- 用于監(jiān)聽。將要被監(jiān)聽的代碼(可能拋出異常的代碼)放在try語句塊之內(nèi),當(dāng)try語句塊內(nèi)發(fā)生異常時,異常就被拋出。
* catch??-- 用于捕獲異常。catch用來捕獲try語句塊中發(fā)生的異常。在編寫多個catch的時候,捕獲范圍大的異常一定要放在捕獲范圍小的異常后面。
finally?-- finally語句塊總是會被執(zhí)行。它主要用于回收在try塊里打開的物力資源(如數(shù)據(jù)庫連接、網(wǎng)絡(luò)連接和磁盤文件)。只有finally塊執(zhí)行完成之后,才會回來執(zhí)行try或者catch塊中的return或者throw語句,如果finally中使用了return或者throw等終止方法的語句,則就不會跳回執(zhí)行,直接停止。
throw??-- 用于拋出一個實例化的異常對象。
throws?-- 用在方法簽名中,用于聲明該方法可能拋出的異常,如果方法真的出現(xiàn)異樣,將交由調(diào)用者來處理。調(diào)用了具有throws申明的方法之后,不管異常是否出現(xiàn),調(diào)用者必須使用try...catch處理。調(diào)用聲明了運行時異常的函數(shù),可以不強制處理,將交給jvm默認處理。
throws 語法如下:
public void info() throws Exception { //body of method }
Exception 是該方法可能引發(fā)的所有的異常,也可以是異常列表,中間以逗號隔開。
Throws拋出異常的規(guī)則: * 如果是不受檢查異常(unchecked exception),即Error、RuntimeException或它們的子類,那么可以不使用throws關(guān)鍵字來聲明要拋出的異常,編譯仍能順利通過,但在運行時會被系統(tǒng)拋出。 * 必須聲明可拋出的任何檢查異常(checked exception)。即如果一個方法可能出現(xiàn)受可查異常,要么用try-catch語句捕獲,要么用throws子句聲明將它拋出,否則會導(dǎo)致編譯錯誤。 * 僅當(dāng)拋出了異常,該方法的調(diào)用者才必須處理或者重新拋出該異常。當(dāng)方法的調(diào)用者無力處理該異常的時候,應(yīng)該繼續(xù)拋出,而不是囫圇吞棗。 * 調(diào)用方法必須遵循任何可查異常的處理和聲明規(guī)則。若覆蓋一個方法,則不能聲明與覆蓋方法不同的異常。聲明的任何異常必須是被覆蓋方法所聲明異常的同類或子類。斷言 assert
什么是斷言?
就是肯定某一個操作的返回結(jié)果是正確的,如果程序執(zhí)行到斷言語句的時候,發(fā)現(xiàn)斷言不正確了,返回結(jié)果是錯誤的了,則通過斷言檢查肯定,會為用戶提示錯誤的信息。在jdk1.4引入了assert關(guān)鍵字。
斷言的使用格式:
assert boolean 表達式; assert boolean 表達式:詳細信息;
默認斷言是不會影響程序正常運行的,在斷言不成立時,也只會將信息顯示出來。除非使用 java -ea 程序 手工啟動斷言。
自定義異常雖然java已經(jīng)提供了很多系統(tǒng)性異常,但在開發(fā)中還是無法滿足實際的需要。所以java允許用戶自定義異常。語法如下:
class 自定義異常類 extends 系統(tǒng)提供的異常類{ public 構(gòu)造函數(shù)(String msg){ super(msg); //... } //... }總結(jié)
處理運行時異常時,采用邏輯去合理規(guī)避,同時輔助使用try-catch處理。
在多重catch塊后面,加一個catch(Exception)來處理可能遺漏的異常。
對于不確定的代碼,也可以加上try-catch,處理潛在的異常。
盡量去處理異常,切記只是簡單的調(diào)用printStackTrace()去打印輸出。
盡量添加finally塊去釋放所占用的資源。
6.具體如果處理異常,要根據(jù)不同的業(yè)務(wù)需求和異常類型去決定。
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/77606.html
摘要:中,任何未處理的受檢查異常強制在子句中聲明。運行時多態(tài)是面向?qū)ο笞罹璧臇|西,要實現(xiàn)運行時多態(tài)需要方法重寫子類繼承父類并重寫父類中已 1、簡述Java程序編譯和運行的過程:答:① Java編譯程序?qū)ava源程序翻譯為JVM可執(zhí)行代碼--字節(jié)碼,創(chuàng)建完源文件之后,程序會先被編譯成 .class 文件。② 在編譯好的java程序得到.class文件后,使用命令java 運行這個 .c...
摘要:中,任何未處理的受檢查異常強制在子句中聲明。運行時多態(tài)是面向?qū)ο笞罹璧臇|西,要實現(xiàn)運行時多態(tài)需要方法重寫子類繼承父類并重寫父類中已 1、簡述Java程序編譯和運行的過程:答:① Java編譯程序?qū)ava源程序翻譯為JVM可執(zhí)行代碼--字節(jié)碼,創(chuàng)建完源文件之后,程序會先被編譯成 .class 文件。② 在編譯好的java程序得到.class文件后,使用命令java 運行這個 .c...
摘要:不過按照經(jīng)驗來說,這類異常要么盡量避免,要么出現(xiàn)了就要做異常處理,從而保證程序的健壯性。業(yè)務(wù)是千變?nèi)f化,但是它們可能產(chǎn)生的異常處理方式是不會變化的,按照這個思路去做異常處理即可。 前言:說到異常體系,可能對于一些初入職場的老鐵會很頭痛,不能夠很清晰的描述異常是個什么情況。那么本文將通過打流水仗的方式給大家介紹一下工作中涉及的異常知識。首先能看到本文,說明也對異常是有了解的,所以文章開頭...
閱讀 2367·2021-11-22 14:56
閱讀 1175·2019-08-30 15:55
閱讀 3206·2019-08-29 13:29
閱讀 1354·2019-08-26 13:56
閱讀 3484·2019-08-26 13:37
閱讀 558·2019-08-26 13:33
閱讀 3349·2019-08-26 13:33
閱讀 2228·2019-08-26 13:33