大战熟女丰满人妻av-荡女精品导航-岛国aaaa级午夜福利片-岛国av动作片在线观看-岛国av无码免费无禁网站-岛国大片激情做爰视频

專注Java教育14年 全國咨詢/投訴熱線:400-8080-105
動力節(jié)點LOGO圖
始于2009,口口相傳的Java黃埔軍校
首頁 學習攻略 Java中處理異常的9個最佳方法與實踐

Java中處理異常的9個最佳方法與實踐

更新時間:2019-08-16 11:10:13 來源:動力節(jié)點 瀏覽2433次

 


今天動力節(jié)點java學院小編專門整理了“Java中處理異常的9個最佳方法與實踐”本文主要是以舉例與代碼展示結(jié)合的方式,讓開發(fā)者更好的理解這9種方式,并指導讀者在不同情況下選擇不同的java異常處理方式。下面隨小編一起來看看吧。



  1、 在Finally中清理資源或者使用Try-With-Resource語句


  通常情況下,你在try中使用了一個資源,比如InputStream,之后需要關(guān)閉它。在這種情況下,一個常見的錯誤是在try的末尾關(guān)閉了資源。


  Java代碼


  public void doNotCloseResourceInTry() {

  FileInputStream inputStream = null;

  try {

  File file = new File("./tmp.txt");

  inputStream = new FileInputStream(file);

  // use the inputStream to read a file

  // do NOT do this

  inputStream.close();

  } catch (FileNotFoundException e) {

  log.error(e);

  } catch (IOException e) {

  log.error(e);

  }

  }


  問題是,只要不拋出異常,這種方法就可以很好地運行。try內(nèi)的所有語句都將被執(zhí)行,資源也會被關(guān)閉。


  但是你在try里調(diào)用了一個或多個可能拋出異常的方法,或者自己拋出異常。這意味著可能無法到達try的末尾。因此,將不會關(guān)閉這些資源。


  所以應該將清理資源的代碼放入Finally中,或者使用Try-With-Resource語句。



  使用Finally


  相比于try,無論是在成功執(zhí)行try里的代碼后,或是在catch中處理了一個異常后,F(xiàn)inally里的內(nèi)容是一定會被執(zhí)行的。因此,可以確保清理所有已打開的資源。


  Java代碼


  public void closeResourceInFinally() {

  FileInputStream inputStream = null;

  try {

  File file = new File("./tmp.txt");

  inputStream = new FileInputStream(file);

  // use the inputStream to read a file

  } catch (FileNotFoundException e) {

  log.error(e);

  } finally {

  if (inputStream != null) {

  try {

  inputStream.close();

  } catch (IOException e) {

  log.error(e);

  }

  }

  }

  }



  Java 7的Try-With-Resource語句


  另一個選擇是Try-With-Resource語句,在introduction to Java exception handling中更詳細地說明了這一點。


  如果你的資源實現(xiàn)了AutoCloseable接口,就可以使用它,這正是大多數(shù)Java標準資源所做的。當你在try子句中打開資源時,它將在try被執(zhí)行后自動關(guān)閉,或者處理一個異常。


  Java代碼


  public void automaticallyCloseResource() {

  File file = new File("./tmp.txt");

  try (FileInputStream inputStream = new FileInputStream(file);) {

  // use the inputStream to read a file

  } catch (FileNotFoundException e) {

  log.error(e);

  } catch (IOException e) {

  log.error(e);

  }

  }



  2、 給出準確的異常處理信息


  你拋出的異常越具體越好。一定要記住,一個不太了解你代碼的同事,也許幾個月后,需要調(diào)用你的方法,并且處理這個異常。


  因此,請確保提供盡可能多的信息,這會使你的API更容易理解。因此,你方法的調(diào)用者將能夠更好的處理異常,或者通過額外的檢查來避免它。


  所以,要盡量能更好地描述你的異常處理信息,比如用NumberFormatException代替IllegalArgumentException,避免拋出一個不具體的異常。


  Java代碼


  public void doNotDoThis() throws Exception {

  ...

  }

  public void doThis() throws NumberFormatException {

  ...

  }



  3、記錄你所指定的異常


  當你在方法中指定一個異常時,你應該在Javadoc中記錄下它。這與前面提到的方法有著相同的目標:為調(diào)用者提供盡可能多的信息,這樣他們就可以避免異常或者更容易地處理異常。


  因此,請確保在Javadoc中添加一個@throws 聲明,并描述可能導致的異常情況。


  Java代碼


  /**

  * This method does something extremely useful ...

  *

  * @param input

  * @throws MyBusinessException if ... happens

  */

  public void doSomething(String input) throws MyBusinessException {

  ...

  }



  4、使用描述性消息拋出異常


  這一最佳實踐的理念與前兩個相似。但這一次,你不用給調(diào)用方法的人提供信息。異常消息會被所有人讀取,同時必須了解在日志文件或監(jiān)視工具中報告異常時發(fā)生了什么。


  因此,應該盡可能準確地描述問題,并提供相關(guān)的信息來了解異常事件。


  別誤會,你不需要寫一段文字,而是應該用1-2個簡短的句子解釋異常的原因。這可以幫助開發(fā)團隊理解問題的嚴重性,同時也使你能夠更容易地分析任何服務事件。


  如果拋出一個特定的異常,它的類名很可能已經(jīng)描述了這種類型的錯誤。所以,你不需要提供很多額外的信息。一個很好的例子就是,當你以錯誤的格式使用字符串時,如NumberFormatException,它就會被類 java.lang.Long的構(gòu)造函數(shù)拋出。


  Java代碼


  try {

  new Long("xyz");

  } catch (NumberFormatException e) {

  log.error(e);

  }


  NumberFormatException已經(jīng)告訴你問題的類型,所以只需要提供導致問題的輸入字符串。如果異常類的名稱不具有表達性,那么就需要提供必要的解釋信息。


  代碼


  17:17:26,386 ERROR TestExceptionHandling:52 - java.lang.NumberFormatException: For input string: "xyz"



  5、最先捕獲特定的異常


  大多數(shù)IDE都可以幫助你做到這點,當你試圖捕獲不確定的異常時,它會報告一個不可到達的代碼塊。


  問題是只有第一個匹配到異常的catch語句才會被執(zhí)行,所以,如果你最先發(fā)現(xiàn)IllegalArgumentException,你將永遠不會到達catch里處理更具體的NumberFormatException,因為它是IllegalArgumentException的一個子類。


  所以要首先捕獲特定的異常類,并在末尾添加一些處理不是很具體異常的catch語句。


  你可以在下面的代碼片段中看到這樣一個try-catch語句的示例。第一個catch處理所有NumberFormatExceptions異常,第二個catch 處理NumberFormatException異常以外的illegalargumentexception異常。


  代碼


  public void catchMostSpecificExceptionFirst() {

  try {

  doSomething("A message");

  } catch (NumberFormatException e) {

  log.error(e);

  } catch (IllegalArgumentException e) {

  log.error(e)

  }

  }



  6、不要在catch中使用Throwable


  Throwable是exceptions 和 errors的父類。當然,你可以在catch子句中使用它,但其實你不應該這樣做。


  如果你在catch子句中使用Throwable,它將不僅捕獲所有的異常,還會捕獲所有錯誤。JVM會拋出錯誤,這是應用程序不打算處理的嚴重問題。典型的例子是OutOfMemoryError或StackOverflowError。這兩種情況都是由應用程序控制之外的情況引起的,無法處理。


  所以,最好不要在catch中使用Throwable,除非你完全確定自己處于一個特殊的情況下,并且你需要處理一個錯誤。


  Java代碼


  public void doNotCatchThrowable() {

  try {

  // do something

  } catch (Throwable t) {

  // don't do this!

  }

  }



  7、不要忽略Exceptions


  你是否曾經(jīng)分析過只有用例的第一部分才被執(zhí)行的bug報告嗎?


  這通常是由一個被忽略的異常引起的。開發(fā)人員可能非常確信它不會被拋出,并添加一個無法處理或無法記錄它的catch語句。當你發(fā)現(xiàn)它的時候,你很可能就會明白一句著名的話“This will never happen”。


  Java代碼


  public void doNotIgnoreExceptions() {

  try {

  // do something

  } catch (NumberFormatException e) {

  // this will never happen

  }

  }


  是的,你可能在分析一個不可能發(fā)生的問題。


  所以,請千萬不要忽略一個例外。你不會知道代碼在將來會發(fā)生什么變化。有些人可能會刪除阻止異常事件的驗證,而沒有意識到這造成了問題。或者拋出異常的代碼被更改,現(xiàn)在拋出了同一個類的多個異常,而調(diào)用的代碼并不能阻止所有這些異常。


  你至少應該寫一個日志信息,告訴每個人,需要檢查一下這個問題。


  Java代碼


  public void logAnException() {

  try {

  // do something

  } catch (NumberFormatException e) {

  log.error("This should never happen: " + e);

  }

  }



  8、不要記錄和拋出一個異常


  這可能是最常被忽略的。你可以在許多代碼片段或者庫文件里發(fā)現(xiàn),有異常會被捕獲、記錄和重新拋出。


  Java代碼


  try {

  new Long("xyz");

  } catch (NumberFormatException e) {

  log.error(e);

  throw e;

  }


  當它發(fā)生時記錄一個異常,然后重新拋出它,以便調(diào)用者能夠適當?shù)靥幚硭@可能會很直觀。但是它會為同一個異常寫多個錯誤消息。


  代碼


  17:44:28,945 ERROR TestExceptionHandling:65 - java.lang.NumberFormatException: For input string: "xyz"

  Exception in thread "main" java.lang.NumberFormatException: For input string: "xyz"

  at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)

  at java.lang.Long.parseLong(Long.java:589)

  at java.lang.Long.(Long.java:965)

  at com.stackify.example.TestExceptionHandling.logAndThrowException(TestExceptionHandling.java:63)

  at com.stackify.example.TestExceptionHandling.main(TestExceptionHandling.java:58)


  不添加任何額外的信息。正如在上述第4個中所解釋的那樣,異常消息應該描述異常事件。堆棧會告訴你在哪個類、方法和行中異常被拋出。


  如果你需要添加額外的信息,應該捕獲異常并將其包裝在一個自定義的信息中。但要確保遵循下面的第9條。


  Java代碼


  public void wrapException(String input) throws MyBusinessException {

  try {

  // do something

  } catch (NumberFormatException e) {

  throw new MyBusinessException("A message that describes the error.", e);

  }

  }


  因此,只需要捕獲一個你想要處理的異常,在方法中指定它,并讓調(diào)用者處理它。



  9、包裝異常


  有時最好捕獲一個標準異常并將其封裝到一個定制的異常中。此類異常的典型例子是應用程序或框架特定的業(yè)務異常。這允許你添加額外的信息,并且也可以為異常類實現(xiàn)一個特殊的處理。


  當你這樣做時,確保引用原始的異常處理。Exception類提供了一些特定的構(gòu)造函數(shù)方法,這些方法可以接受Throwable作為參數(shù)。否則,你將丟失原始異常的堆棧跟蹤和消息,這將使你很難分析導致異常的事件。


  Java代碼


  public void wrapException(String input) throws MyBusinessException {

  try {

  // do something

  } catch (NumberFormatException e) {

  throw new MyBusinessException("A message that describes the error.", e);

  }

  }


以上就是動力節(jié)點java學院小編介紹的“Java中處理異常的9個最佳實踐”的內(nèi)容,希望對大家有幫助,更多精彩內(nèi)容請關(guān)注動力節(jié)點java學院官網(wǎng)。



提交申請后,顧問老師會電話與您溝通安排學習

免費課程推薦 >>
技術(shù)文檔推薦 >>
主站蜘蛛池模板: 成人午夜大片免费视频77777 | 亚洲欧美一二三区 | 国内精品久久久久久影院网站小说 | 一级一级 a爱片免费视频 | 精品无人乱码区1区2区3区 | 色多多h | 爱爱小视频免费 | 日日摸夜夜嗷嗷叫日日拍 | 四虎精品在线观看 | 4huh34四虎最新888 | 爱爱免费网站 | 国产精品亚洲专区在线播放 | 亚洲高清中文字幕一区二区三区 | 97精品国产高清在线看入口 | 最新国产福利在线 | 四虎影院在线免费观看视频 | 亚洲精品久久久久影 | 久久网综合 | 中文字幕专区在线亚洲 | 久久精品一区二区国产 | 亚洲爱婷婷色婷婷五月 | 色综合精品 | 最新国产午夜精品视频不卡 | 国产激情一区二区三区四区 | 国产麻豆va精品视频 | 在线播放精品 | 精品乱人伦一区二区 | 四虎爱爱 | 伊人免费视频网 | 天天综合亚洲 | 亚洲高清一区二区三区久久 | 91精品综合久久久久3d动漫 | 九九热视频这里只有精品 | 国产高清免费午夜在线视频 | 色噜噜国产精品视频一区二区 | 尤物视频在线 | 伊人成人久久 | 精品日韩在线视频一区二区三区 | 中文字幕精品在线观看 | 国产中文欧美 | 免费v片在线观看无遮挡 |