Java異常處置之try...catch...語句的應用進階。本站提示廣大學習愛好者:(Java異常處置之try...catch...語句的應用進階)文章只能為提供參考,不一定能成為您想要的結果。以下是Java異常處置之try...catch...語句的應用進階正文
try就像一個網,把try{}外面的代碼所拋出的異常都網住,然後把異常交給catch{}外面的代碼行止理。最初履行finally當中的代碼。不管try中代碼有無異常,也不管catch能否將異常捕捉到,finally中的代碼都必定會被履行。
固然 Java 履行時代體系所供給的預設處置器對除錯很有效,你平日想要本身處置破例。如許做有兩個長處:第一,它讓你修改毛病。第二,它可以免程式主動終止。每當毛病產生時,假如你的程式就停滯並且列印出堆疊追蹤,年夜多半的應用者都邑覺得很迷惑。很榮幸,你很輕易就可以防止這類情況。
要戒備而且處置履行時代毛病,只需將你要監督的程式碼放在 try 區塊裡便可。在 try 區塊以後緊接著在 catch 子句裡指定你願望捕獲的破例型態
毛病捕獲例子:
try { code; //將本身的代碼放在個中; } catch(e) //假如下面的代碼有毛病,這裡就捕捉 { alert(e.number); //取得毛病信息 }
例如:
import java.io.*;//挪用io包 public class SimpleCharInOut { public static void main(String args[]) { char ch=' ';//界說個字符ch初始為‘ ' System.out.println(" Enter a character please");//在屏幕上輸入Enter a character please try {//你要監督的程式碼放在 try 區塊裡便可。在 try 區塊以後緊接著在 catch 子句裡指定你願望捕獲的破例型態 ch=(char)System.in.read();//將從鍵盤輸出的字符賦給ch } catch(IOException e) //假如下面的代碼有毛病,這裡就捕捉 { } ;//毛病後不停止操作 System.out.println("You're entered character:" + ch);// 在屏幕上輸入You're entered character: //和ch的值 } }
我們在寫Java的try..catch的時刻,常常須要在最初加上finally子句封閉一些IO資本,好比
InputStream is; try{ is=openInputStream(); // do something }catch(IOException e){ e.printStaceTrace(e); }finally{ try{ is.close(); }catch(IOException e ){ } }
然則在應用這類形式時,即便是Java熟手在行,偶然也會犯一些毛病。好比下面這段代碼,當openInputStream()函數在履行進程中拋出異常,那末變量is的值仍為null,此時履行is.close()會拋出NullPointerException. 因為NullPoiterException不是IOException的子類,是以它不克不及被catch塊捕捉,而是直接往挪用層拋出去. 一種改良的寫法就是在封閉流的時刻先輩行非空斷定,但如許代碼會顯得很煩瑣。小我以為比擬優雅的寫法是直接挪用commons-io包供給的IOUtils.closeQuitely()辦法封閉流(或許本身封裝一個closeQuitely()辦法)。
應用這類寫法還有一種利益,就是當碰到封閉多個IO資本時不輕易失足,好比上面這段代碼:
InputStream is; OutputStream os ; try{ is=openInputStream(); // do something }catch(IOException e){ e.printStaceTrace(e); }finally{ try{ if (is != null ) is.close(); if (os != null ) os.close(); }catch(IOException e ){ } }
當is.close()產生毛病的時刻,os.close()就沒法被履行,從而招致os所援用的資本沒有被釋放。
或許Oracle也認為這類try .. catch ... finally的樣板代碼太沒需要,是以在JDK 7中對try 子句停止了一些改革,免除編寫一些手動封閉資本的代碼,讓代碼看起來更緊湊更簡練。好比下面的代碼在JDK 7下可以改成:
try( InputStream is = openInputStream(); OutputStream os = openOutStream(); ){ // do something }catch(IOException e){ e.printStaceTrace(e); }
Oracle把這裡的try(..)語句叫做try-with-resource語句。須要留意的是,try(.. )中變量所援用的對象都必需是完成了java.io.AutoClosable接口的實例,當加入try ..catch塊時,JDK會主動挪用close()辦法。 也就是說,try-with-resource語句中的resource(資本)不只限於IO資本。
這裡有需要對try-with-resource語句的一些細節停止彌補解釋:
JDK會確保一切資本的close()辦法被挪用,不論close()辦法能否拋出異常, 而挪用的次序和資本聲明的次序相反
try-with-resource語句中一切拋出的異常都邑被捕捉。假如多個異常被拋出,前面所拋出的異常會被suppress(克制)在前一個異常中,catch塊終究只拿到最早拋出的誰人異常。可以順次經由過程挪用Throwable類界說的getSuppressed()取得被suppressed(克制)的異常。
照樣下面誰人例子,
當加入try .. catch.塊的時刻,JDK會先挪用os.close(),然後是is.close(), 假如兩次close()都拋出IOException, 那末is.close()所拋出的異常會被suppress(克制)在os.close()所拋出的異常中,終究catch塊只捕捉到os.close()所拋出的異常。可以經由過程getSuppressed()辦法拿到is.close()所拋出的異常。
假如挪用openInputStream()的時刻就產生IOException,那末openOutputStream()就不會被挪用,os.close()和is.close()也不會被挪用, catch塊捕獲到 挪用openInputStream()時所拋出的異常。
假如挪用openOutputStream()產生IOException(用記號 e1表現), 那末is.close()照樣會被挪用, 假如此時is.close()又拋出IOException(用記號 e2表現),那末e2會被suppress到e1中,而catch塊捕獲到的異常是 e1.
除對try塊做了改革,JDK 7還對catch部門停止了簡化,許可把多個catch子句歸並。 好比:
try( InputStream is = openInputStream(); OutputStream os = openOutStream(); ){ // do something }catch(IOException | XMLParseException | XPathException e){ e.printStaceTrace(e); }
另外,當你從新拋出多個異常時,不再須要具體界說異常類型了,編譯器曾經曉得你詳細拋出的是哪一個異常了。你只需在辦法界說的時刻聲明須要拋出的異常便可。好比
// 固然這裡用Exception婚配拋出的IOException,到編譯器曉得現實上拋給下層的異常是IOException public void doIO() throws IOException { try{ throw new IOException(); }catch(Exception e){ throw e; } }
PS : 這個特征我想不到會帶來甚麼利益
JDK 7還有其他風趣的語法新特征,好比二進制字面量,用下劃線朋分長數字,泛型參數的類型揣摸,switch支撐字符串婚配等等。 如今JDK 8又引入了一些有效的特征。在不須要斟酌向後兼容的條件下, 恰當並靈巧應用一些語法特征,可讓我們的代碼在必定水平上顯得更清楚,更簡練。