csusky

          常用鏈接

          統(tǒng)計(jì)

          最新評(píng)論

          JAVA中的異常處理

          在JAVA中,如果某個(gè)方法不能夠按照正常的途徑完成它的任務(wù),就可以通過(guò)另外一個(gè)途徑退出方法。在這種情況下,方法并不立刻返回,而是拋出一個(gè)封裝了錯(cuò)誤信息的對(duì)象。需要注意的是,這個(gè)方法將會(huì)立刻退出,且并不返回正常情況下的值。此外,調(diào)用這個(gè)方法的代碼也將無(wú)法執(zhí)行,取而代之的是,異常處理機(jī)制開始搜索能夠處理這種錯(cuò)誤條件的異常處理器。

          如果在子類中覆蓋了超類的一個(gè)方法,那么子類方法聲明的已檢查異常不能超過(guò)超類方法中聲明的異常圍。(也就是說(shuō)子類中拋出的異常范圍更小或者根本不拋出異常)。需要說(shuō)明的是,如果超類方法沒有拋出任何異常,子類也不能拋出任何已檢查異常。例如,如果覆蓋JComponent.paintComponent()方法,那么    由于超類中沒有拋出任何異常,所以自定義的paintComponent()方法也不能拋出任何異常。

          如何拋出異常:
          譬如在讀一個(gè)輸入流時(shí),如果期待的字節(jié)數(shù)為1024,而當(dāng)讀到700字節(jié)的時(shí)候遇到一個(gè)EOF信號(hào),這是我們未預(yù)期的,正是我們要拋出的異常,下面就是拋出改異常的語(yǔ)句

          1String readData() throws EOFException {
          2   while ({
          3      if(!in.hasNext()) {
          4          if(n<len)
          5            throw new EOFException();
          6     }
            
          7  }

          8}

          這是拋出已存在標(biāo)準(zhǔn)的異常,步驟為:
          1.找到一個(gè)合適的異常類
          2.創(chuàng)建該類的對(duì)象
          3.將異常拋出
          一旦拋出異常,該方法就不可能返回到調(diào)用者,這就意味著不必為返回的默認(rèn)值或錯(cuò)誤代碼擔(dān)憂了。

          在程序中可能會(huì)遇到任何標(biāo)準(zhǔn)異常都無(wú)法正確描述清楚的問(wèn)題,這時(shí)候就需要定義自己的異常類,定義自己的異常類需要繼承自Exception 或者其子類,如繼承自IOException  一般要為自定義的Exception定義兩個(gè)構(gòu)造函數(shù),一個(gè)是默認(rèn)的無(wú)參的構(gòu)造函數(shù),另一個(gè)是帶一個(gè)描述詳細(xì)錯(cuò)誤信息String的構(gòu)造函數(shù)(超類的toString()方法會(huì)打印出這些詳細(xì)信息。

          1public class MyException extends IOException {
          2
          3    MyException () {}
          4    
          5    MyException (String info) {
          6       super(info);
          7   }

          8}

          現(xiàn)在就可以像使用標(biāo)準(zhǔn)Exception類一樣使用自定義的Exception類了

          1String readData() throws MyException {
          2   while () {
          3      if(!in.hasNext()) {
          4          if(n<len)
          5            throw new MyException();
          6    }
            
          7 }

          8}

          可以用超類Throwable類的getMessage方法得到詳細(xì)的錯(cuò)誤描述信息。或者toString()方法打印該信息。

          捕獲異常:
          如果語(yǔ)句exp1有可能拋出一個(gè)異常,或者說(shuō)是調(diào)用了能夠拋出一個(gè)異常的方法,那么我們可以在程序中捕獲該異常

          1try {
          2 exp1;
          3 exp2;
          4 .
          5
          6}
           catch(Exception e) {
          7   e.
          8}

          9

          或者是并不捕獲,再次拋出該異常

          再次拋出異常,異常鏈:
          可以在catch塊中再次拋出新的異常,這樣可以隱藏原始的錯(cuò)誤細(xì)節(jié)

          1catch(SQLException sqle) {
          2    throw new ServletException("caused by SQLException "+e.getMessage());
          3}

          另一種更好的方法
          既拋出高級(jí)的異常,又不會(huì)丟失原始的異常信息。

          1}catch(SQLException sqle) 
          2    Throwable ta=new ServletException("caused by SQLException");
          3    ta.setCause(e);
          4    throw ta;
          5}

          6當(dāng)捕獲拋出的異常ta時(shí),可以用ta.getCause(),得到原始的異常


          finally子句,發(fā)生三種情況時(shí),會(huì)執(zhí)行finally子句
          1.try代碼正常執(zhí)行
          2.try代碼拋出一個(gè)在catch子句中捕獲的異常
          3.try代碼拋出一個(gè)未在catch子句中捕獲的異常
          就是說(shuō)無(wú)論異常如何,finally子句中的代碼都會(huì)執(zhí)行
          一般把一些資源回收的工作交給finally子句

          最好把try-catch塊和try-finally塊分開,這樣可以提高代碼的清晰度

           1try {
           2   try {
           3      //可能拋出IOException的語(yǔ)句
           4    }
           finally {
           5    is.close();
           6 }

           7}
           catch(IOExceotion e) {
           8   
           9}

          10

          這樣的另外一個(gè)好處是,可以catch到finally子句中拋出的異常。這也就引發(fā)了另外一個(gè)問(wèn)題,如果在try和finally中都拋出了異常,而且是不同類型的,那么最后返回的是那一個(gè)呢?答案是finally中拋出的異常會(huì)覆蓋try中拋出的異常。從而丟失了try當(dāng)中拋出的異常信息,讓拋出該方法的使用者不能跟蹤異常信息。所以,在finally中執(zhí)行的語(yǔ)句最好是不要拋出異常,但是不幸的是我們有時(shí)候不得不在finally中執(zhí)行一些清楚操作如:關(guān)閉輸入流InputStream,但是InputStream類的設(shè)計(jì)者并沒有這么設(shè)計(jì)(將會(huì)拋出異常)。

          由于finally子句總是會(huì)執(zhí)行,所以在finally中包含return值時(shí),是很危險(xiǎn)的。假設(shè)我們利用return語(yǔ)句從try中返回,在方法返回之前finally子句的內(nèi)容將會(huì)被執(zhí)行。如果finally子句當(dāng)中也包含一個(gè)return 語(yǔ)句,那么這個(gè)return語(yǔ)句所返回的值,將會(huì)覆蓋原先return的值。

          1public int f(int n) {
          2  try {
          3      return n*n;
          4    }
           finally {
          5     if(n==2)
          6       return 2;
          7  }

          8}

          在這里如果調(diào)用i=f(2);那么i的值將會(huì)是2而不是期望的2*2=4


          最后最重要的一點(diǎn),關(guān)于一個(gè)方法是捕獲一個(gè)異常還是拋出給調(diào)用他的方法
          有一點(diǎn)規(guī)則   
                                          早拋出,晚捕獲,盡量把異常拋出給調(diào)用它的函數(shù)

          posted on 2008-02-26 14:05 曉宇 閱讀(530) 評(píng)論(0)  編輯  收藏 所屬分類: JAVA基礎(chǔ)

          主站蜘蛛池模板: 大埔区| 民权县| 丘北县| 五华县| 新昌县| 礼泉县| 精河县| 三台县| 金坛市| 额尔古纳市| 鄂托克前旗| 五河县| 高碑店市| 当雄县| 黎平县| 吴川市| 建昌县| 高陵县| 鱼台县| 辽中县| 同心县| 密山市| 湖南省| 株洲县| 临沧市| 徐水县| 临泉县| 孝昌县| 龙胜| 大洼县| 利津县| 江门市| 竹溪县| 乡城县| 平果县| 黄梅县| 古田县| 公主岭市| 娄烦县| 伽师县| 云阳县|