一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java異常處理之try...catch...語句的使用進階

Java異常處理之try...catch...語句的使用進階

2020-01-20 11:08goldensun JAVA教程

這篇文章主要介紹了Java異常處理之try...catch...語句的使用進階,重點在于牽扯相關IO使用時的資源調配情況,需要的朋友可以參考下

try就像一個網,把try{}里面的代碼所拋出的異常都網住,然后把異常交給catch{}里面的代碼去處理。最后執行finally之中的代碼。無論try中代碼有沒有異常,也無論catch是否將異常捕獲到,finally中的代碼都一定會被執行。
雖然 Java 執行時期系統所提供的預設處理器對除錯很有用,你通常想要自己處理例外。這樣做有兩個優點:第一,它讓你修正錯誤。第二,它可以避免程式自動終止。每當錯誤發生時,如果你的程式就停止而且列印出堆疊追蹤,大多數的使用者都會感到很困惑。很幸運,你很容易就能避免這種情形。
要防備并且處理執行時期錯誤,只要將你要監視的程式碼放在 try 區塊里即可。在 try 區塊之后緊接著在 catch 子句里指定你希望捕捉的例外型態
錯誤捕捉例子: 

?
1
2
3
4
5
6
7
try
{
  code; //將自己的代碼放在其中;
} catch(e) //如果上面的代碼有錯誤,這里就捕獲
{
  alert(e.number); //獲得錯誤信息
}

 
例如:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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資源,比如

?
1
2
3
4
5
6
7
8
9
10
11
12
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資源時不容易出錯,比如下面這段代碼:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
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下可以改成:

?
1
2
3
4
5
6
7
8
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子句合并。 比如:

?
1
2
3
4
5
6
7
8
9
try(
 InputStream is = openInputStream();
 OutputStream os = openOutStream();
){
 // do something 
}catch(IOException | XMLParseException | XPathException e){
  e.printStaceTrace(e);
}

此外,當你重新拋出多個異常時,不再需要詳細定義異常類型了,編譯器已經知道你具體拋出的是哪個異常了。你只需在方法定義的時候聲明需要拋出的異常即可。比如

?
1
2
3
4
5
6
7
8
// 雖然這里用Exception匹配拋出的IOException,到編譯器知道實際上拋給上層的異常是IOException
    public void doIO() throws IOException {
      try{
        throw new IOException();
      }catch(Exception e){
        throw e;
      }
    }

PS : 這個特性我想不到會帶來什么好處
 
JDK 7還有其他有趣的語法新特性,比如二進制字面量,用下劃線分割長數字,泛型參數的類型推斷,switch支持字符串匹配等等。 現在JDK 8又引入了一些有用的特性。在不需要考慮向后兼容的前提下, 適當并靈活運用一些語法特性,可以讓我們的代碼在一定程度上顯得更清晰,更簡潔。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本黄视频在线播放 | 91精品国产91久久久久久 | 国产草 | 免费高清视频日本 | 精品久久香蕉国产线看观看麻豆 | avtt天堂网手机版亚洲 | 国产精品福利 | 亚洲视频日韩 | 嫩草在线视频www免费观看 | 国产精品福利一区二区亚瑟 | 美国xxnx| 朝鲜女人free性hu | 日韩在线一区二区三区免费视频 | 日本69视频在线观看 | 18国产精品白浆在线观看免费 | 蜜桃视频一区二区 | 亚洲骚图 | 国产精品久久久 | 色婷婷网 | 韩日一区二区三区 | 午夜毛片在线观看 | 风间由美一区二区播放合集 | 999任你躁在线精品免费不卡 | 国产精品区牛牛影院 | 亚洲香蕉网久久综合影院3p | 亚洲免费闲人蜜桃 | 欧美日本一道高清免费3区 欧美人做人爱a全程免费 | 国产成年人在线观看 | 好大好猛好深好爽视频 | 亚洲、国产综合视频 | 5555kkkk香蕉在线观看 | 亚洲国产果果在线播放在线 | 色噜噜 男人的天堂在线观看 | 精品欧美小视频在线观看 | 国产自在自拍 | 男人猛进女人屁股免费 | 国产有码在线 | 婷婷综合亚洲 | 日韩伦理在线看 | 国产精品久久国产精品99盘 | 91精品大神国产在线播放 |