首先,您應(yīng)該知道的是Java 提供了兩種Exception 的模式,一種是執(zhí)行的時(shí)候所產(chǎn)生的Exception (Runtime Exception),另外一種則是受控制的Exception (Checked Exception)。所有的Checked Exception 均從java.lang.Exception 繼承而來,而Runtime Exception 則繼承java.lang.RuntimeException 或java.lang.Error (實(shí)際上java.lang.RuntimeException 的上一層也是java.lang.Exception)。
當(dāng)我們撰寫程序的時(shí)候,我們很可能會(huì)對選擇某種形式的Exception 感到困擾,到底我應(yīng)該選擇Runtime Exception 還是Checked Exception ?
其實(shí),在運(yùn)作上,我們可以通過Class 的Method 如何產(chǎn)生某個(gè)Exception以及某個(gè)程序如何處理這個(gè)被產(chǎn)生來的Exception 來了解它們之間的差異。
uncheckException runtimeException ArithmeticException Arithmetic error, such as divide-by-zero.ArrayIndexOutOfBoundsException Array index is out-of-bounds.ArrayStoreException Assignment to an array element of an incompatible type.ClassCastException Invalid cast.IllegalArgumentException Illegal argument used to invoke a method.IllegalMonitorStateException Illegal monitor operation, such as waiting on an unlocked thread.IllegalStateException Environment or application is in incorrect state.IllegalThreadStateException Requested operation not compatible with current thread state.IndexOutOfBoundsException Some type of index is out-of-bounds.NegativeArraySizeException Array created with a negative size.NullPointerException Invalid use of a null reference.NumberFormatException Invalid conversion of a string to a numeric format.SecurityException Attempt to violate security.StringIndexOutOfBounds Attempt to index outside the bounds of a string.TypeNotPresentException Type not found. (Added by J2SE 5.)UnsupportedOperationException An unsupported operation was encountered.下面是CheckExceptionClassNotFoundException Class not found.CloneNotSupportedException Attempt to clone an object that does not implement the Cloneable interface.IllegalAccessException Access to a class is denied.InstantiationException Attempt to create an object of an abstract class or interface.InterruptedException One thread has been interrupted by another thread.NoSuchFieldException A requested field does not exist.NoSuchMethodException A requested method does not exist. 首先我們先建立一個(gè)Exception:
在這三個(gè)method 中,我們看到了method1 和method2 的程序碼內(nèi)都會(huì)產(chǎn)生Exception,但method3 的程序碼中(大括號內(nèi)),并沒產(chǎn)生Exception,但在method3 的定義中,暗示了這個(gè)method 可能產(chǎn)生CException。
呼叫method1() 的程序,必須將method1() 包含在try 與catch 中,如:
雖然包含在try 與catch 中,并不表示這段程序碼一定會(huì)收到CException,但它的用意在于提醒呼叫者,執(zhí)行這個(gè)method 可能產(chǎn)生的意外,而使用者也必須要能針對這個(gè)意外做出相對應(yīng)的處理方式。
當(dāng)使用者呼叫method2() 時(shí),并不需要使用try 和catch 將程序碼包起來,因?yàn)閙ethod2 的定義中,并沒有throws 任何的Exception ,如
程序在執(zhí)行的時(shí)候,也不見得會(huì)真的產(chǎn)生NullPointerException ,這種Exception 叫做runtime exception 也有人稱為unchecked exception ,產(chǎn)生Runtime Exception 的method (在這個(gè)范例中是method2) 并不需要在宣告method 的時(shí)候定義它將會(huì)產(chǎn)生哪一種Exception 。
在testException 的method3() 中,我們看到了另外一種狀況,也就是method3里呼叫了method1() ,但卻沒有將method1 包在try 和catch 之間。相反,在method3() 的定義中,它定義了CException,實(shí)際上就是如果method3 收到了CException ,它將不處理這個(gè)CException ,而將它往外丟。當(dāng)然,由于method3 的定義中有throws CException ,因此呼叫method3 的程序碼也需要有try catch 才行。
因此從程序的運(yùn)作機(jī)制上看,Runtime Exception與Checked Exception 不一樣,然而從邏輯上看,Runtime Exception 與Checked Exception 在使用的目的上也不一樣。
一般而言,Checked Exception 表示這個(gè)Exception 必須要被處理,也就是說程序設(shè)計(jì)者應(yīng)該已經(jīng)知道可能會(huì)收到某個(gè)Exception(因?yàn)橐猼ry catch住) ,所以程序設(shè)計(jì)者應(yīng)該能針對這些不同的Checked Exception 做出不同的處理。
而Runtime Exception 通常會(huì)暗示著程序上的錯(cuò)誤,這種錯(cuò)誤會(huì)導(dǎo)致程序設(shè)計(jì)者無法處理,而造成程序無法繼續(xù)執(zhí)行下去。
看看下面的例子:
這段程序碼在Compile 時(shí)并沒問題,但在執(zhí)行時(shí)則會(huì)出現(xiàn)ArrayIndexOutOfBoundException 的例外,在這種狀況下,我們亦無法針對這個(gè)Runtime Exception 做出有意義的動(dòng)作,這就像是我們呼叫了testException 中的method2 ,卻引發(fā)了它的NullPointerException 一樣,在這種狀況下,我們必須對程序碼進(jìn)行修改,從而避免這個(gè)問題。
因此,實(shí)際上我們應(yīng)該也必須要去抓取所有的Checked Exception,同時(shí)最好能在這些Checked Exception 發(fā)生的時(shí)候做出相對應(yīng)的處理,好讓程序能面對不同的狀況。
然而對于Runtime Exception ,有些人建議將它c(diǎn)atch 住,然后導(dǎo)向其它地方,讓程序繼續(xù)執(zhí)行下去,這種作法并非不好,但它會(huì)讓我們在某些測試工具下認(rèn)為我們的程序碼沒有問題,因?yàn)槲覀儗untime Exception "處理"掉了,事實(shí)卻不然!譬如很多人的習(xí)慣是在程序的進(jìn)入點(diǎn)后用個(gè)大大的try catch 包起來,如:
在這種情況下,我們很可能會(huì)不知道發(fā)生了什么Exception 或是從哪一行發(fā)出的,因此在面對不同的Checked Exception時(shí),我們可已分別去try catch它。而在測試階段時(shí),如果碰到Runtime Exception ,我們可以讓它就這樣發(fā)生,接著再去修改我們的程序碼,讓它避免Runtime Exception,否則,我們就應(yīng)該仔細(xì)追究每一個(gè)Exception ,直到我們可以確定它不會(huì)有Runtime Exception 為止!
對于Checked Exception 與Runtime Exception ,我想應(yīng)該有不少人會(huì)有不同的觀點(diǎn),無論如何,程序先要能執(zhí)行,這些Exception 才有機(jī)會(huì)產(chǎn)生。因此,我們可以把這些Exception 當(dāng)成是Bug ,也可以當(dāng)成是不同的狀況(Checked Exception),或當(dāng)成是幫助我們除錯(cuò)的工具(Runtime Exception),但前提是我們需要處理這些Exception ,如果不處理,那么問題或狀況就會(huì)永遠(yuǎn)留在那里
Powered by: BlogJava Copyright © 云云