Java編程中異常處理的優(yōu)劣之道

字號(hào):

Java編程中的異常處理是一個(gè)很常見的話題了,幾乎任何一門介紹性的Java課程都會(huì)提到異常處理。不過(guò),我認(rèn)為很多人其實(shí)并沒有真正掌握正確處理異常情況的方法和策略,多也就不過(guò)了解個(gè)大概,知道點(diǎn)概念。本文就對(duì)三種不同程度和質(zhì)量的Java異常處理進(jìn)行了討論,所闡述的處理異常的方式按手法的高下分為:
    好,不好和惡劣三種。
    同時(shí)向你提供了一些解決這些問(wèn)題的技巧。
    首先解釋一些java異常處理中必須搞清楚的定義和機(jī)制。Java語(yǔ)言規(guī)范將自Error類或RuntimeException類衍生出來(lái)的任何違例都稱作“不可檢查”(Unchecked)異常;其他所有異常則稱作“可檢查”(Checked)異常。
    所謂可檢查異常,是指我們應(yīng)該自行處理的異常。至于處理的手段,要么加以控制(try catch),要么通告(throws)他們有可能產(chǎn)生。通常,應(yīng)捕捉那些已知如何處理的異常,而通告那些不知如何處理的異常。
    而對(duì)那些不可檢查異常來(lái)說(shuō),他們要么在我們的控制之外(Error),要么是我們首先就不該允許的情況(RuntimeException).
    至于異常的指定,Java的規(guī)則非常簡(jiǎn)單:一個(gè)方法必須通告自己可能產(chǎn)生的所有可檢查異常。編寫自己的方法時(shí),并不一定要通告出方法實(shí)際可能產(chǎn)生的每一個(gè)異常對(duì)象,要想理解什么時(shí)候必須要方法的throws叢句來(lái)通告異常,就必須知道對(duì)一個(gè)異常來(lái)說(shuō),他只有可能在下面四種情況下才會(huì)產(chǎn)生:
    1.調(diào)用了可能產(chǎn)生異常的方法。比如BufferedReader類的readLine方法。該方法通告java.io.IOException異常
    2.偵測(cè)到一個(gè)錯(cuò)誤,并用throw語(yǔ)句產(chǎn)生異常。
    3.出現(xiàn)一個(gè)編程錯(cuò)誤。比如a[-1] = 0。
    4.Java產(chǎn)生內(nèi)部錯(cuò)誤。
    如果出現(xiàn)頭兩種情況之一,必須告訴打算使用自己方法的人:假如使用這個(gè)方法,可能造成一個(gè)異常的產(chǎn)生(即在方法頭上使用throws),一個(gè)簡(jiǎn)單的記憶方法:
      只要含有throw,就要通告throws。如果一個(gè)方法必須同時(shí)處理多個(gè)異常,就必須在頭內(nèi)指出所有異常。就像下例展示的那樣,用逗號(hào)對(duì)他們進(jìn)行分割:
    1234567
     class Animation
    {
    public Image loadImage(Strint s) throws EOFException,MalformedURLException
    {
    …………
    }
    }
    然而,我們不需要通告內(nèi)部java錯(cuò)誤,也不應(yīng)該通告自RuntimeException衍生出來(lái)的異常。
    好的異常處理
    好異常處理提供了處理程序錯(cuò)誤的統(tǒng)一機(jī)制。事實(shí)上,Java語(yǔ)言通過(guò)向調(diào)用者提出異常警告的方式而顯著地提升了軟件開發(fā)中的異常處理能力。這種方式把Java語(yǔ)言中的“方法(method)”進(jìn)行了擴(kuò)展和增強(qiáng),使之包括了自身的錯(cuò)誤條件。下面就讓我們看一個(gè)例子,這個(gè)例子說(shuō)明了這種情況。
    以下是FileInputStream構(gòu)造器之一的原型:
    public FileInputStream(String name) throws FileNotFoundException Java
    的方法和構(gòu)造器必須聲明他們?cè)诒徽{(diào)用時(shí)可能“扔出”的異常,采用的關(guān)鍵字就是“throws”。這種在方法原型中出現(xiàn)的異常提示增加了編程的可靠性。
    顯而易見,這種方式是向方法的調(diào)用者提示了可能出現(xiàn)的異常條件,這樣調(diào)用者就可以對(duì)這些異常作出適當(dāng)?shù)南鄳?yīng)處理。以下代碼示意我們是如何捕獲并且處理FileNotFoundException 這一異常的:
    1234567891011
     try
    {
     FileInputStream fis = new FileInputStream(args[0]);
     // other code here ...
    }
    catch (FileNotFoundException fnfe)
    {
     System.out.println("File: " + args[0] + " not found. Aborting.");
     System.exit(1);
     }
    Java異常處理還有其他一些優(yōu)秀的特性,這就是可檢查異常、用戶定義異常和在JDK 1.4中推出的新型Java記錄API(Java Logging API)。java.lang.Exception的所有子類都屬于可檢查異常??蓹z查異常(checked exception)是扔出該異常的方法所必須提示的異常,這種異常必須被捕獲或者向調(diào)用者提示。用戶定義異常(User-defined exceptions)是定制的異常類,這種異常類擴(kuò)展了java.lang.Exception類。優(yōu)良的Java程序規(guī)定定制異常封裝、報(bào)告和處理他們自己獨(dú)有的情況。新的Java記錄API(logging API)則可以集中記錄異常。