最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一篇文章解決Java異常處理

 更新時間:2020年09月03日 10:03:57   作者:今天的喝了碗雞湯  
這篇文章主要給大家介紹了關(guān)于如何通過一篇文章解決Java異常處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

與異常相關(guān)的內(nèi)容其實很早就想寫了,但由于各種原因(懶)拖到了現(xiàn)在。在大二開學(xué)前夜(今天是8.31)完成這篇博客,也算完成了暑期生活的一個小心愿。

以下內(nèi)容大多總結(jié)自《Java核心技術(shù) 卷Ⅰ》,同時也加上了一些華東師范大學(xué)陳良育老師在《Java核心技術(shù)》Mooc中所講的內(nèi)容。

一、引例

假定你希望完成一個read方法,它的作用是讀取一個文件中的內(nèi)容并進行相關(guān)處理,如果你從未學(xué)過處理異常的方法,你可能會這樣寫:

public void read(String filename)
{
 var in = new FileInputStream(filename);
 int b;
 while((b = in.read()) != -1)
 {
  ... 
 }
}

問題在于,F(xiàn)ileInputStream的構(gòu)造器要求傳入的filename是已經(jīng)存在的一個文件的名稱,如果文件名不存在,那么程序?qū)惓=K止,可能導(dǎo)致用戶在運行程序期間所做的工作全部丟失,這顯然不是我們希望看到的。
正確的做法之一是增加一個異常處理機制,將控制權(quán)從產(chǎn)生錯誤的地方轉(zhuǎn)移到能夠處理這種錯誤的處理器中。這樣就可以盡可能的減少損失。

public void read(String filename)
{
  try
  {
   var in = new FileInputStream(filename);
   int b;
   while((b = in.read()) != -1)
   {
     ...
   }
  }
  catch(IOException exception)
  {
   ...//處理錯誤
  }
}
//里面可能有些代碼你暫且還不明白,不過沒關(guān)系,之后會認真講解。

二、異常的分類與類型

在Java中,每種異常都是一個類(如上例中的IOException),每個異常對象都是一個實例。

  1. 所有的異常都是由Throwable類繼承而來。
  2. Throwable類的下一層有兩個分支:Error類和Exception類
  3. Exception類又分解為RuntimeException(編程錯誤導(dǎo)致的異常)與IOException(其他異常)

Error類:描述Java運行時系統(tǒng)內(nèi)部錯誤和資源耗盡錯誤。 RuntimeException類:編程錯誤。例如數(shù)組越界訪問、錯誤的強制類型轉(zhuǎn)換、訪問null指針等。
IOException類:其他異常。例如打開不存在的文件等等。

對于Error異常,我們無能為力;而對于RuntimeException異常,我們要做的是預(yù)防而非處理,譬如在程序中寫好檢測數(shù)組下標是否越界的代碼、在使用變量前檢測它是否為null;我們重點處理的對象是IOException異常。

鑒于上述特性,Error與RuntimeException異常在Java語言規(guī)范中被稱為非檢查型異常;IOException稱為檢查型異常。編譯器只會幫助你檢查是否為所有的檢查型異常提供了異常處理器。

三、處理檢查型異常之方法一:聲明與拋出

如果你知道一個方法會產(chǎn)生某種(或多種)檢查型異常,但又不想處理這個異常(或無法處理),可以選擇僅聲明該類異常,將異常的處理交由調(diào)用這個方法的人。

具體的操作方式為:在方法名稱后面加上 throws + 異常類型,程序中如果真的遇到了這種異常,則 throw + 異常類的對象拋出異常。

String readData(Scanner in) throws EOFException
{
  ...
  while(...)
  {
   if(!in.hasNext())
   {
     if(n < len)//遇見EOFException異常
     {
      throw new EOFException();//拋出異常
     }
     ...
   }
   return s;
  }
}

聲明異常時請注意:

  • 如果一個方法可能拋出多個檢查型異常,則必須列出所有的檢查型的異常類。(否則編譯器會發(fā)出一個錯誤消息)
public void read(String filename) throws FileNotFoundException, EOFException
  • 如果子類覆蓋了父類中的一個方法,則子類中該方法對異常的聲明范圍不能超過父類(即子類中覆蓋的方法要么拋出更具體的異常,要么不拋出異常)。
  • 如果一個方法聲明它會拋出一個異常,那么這個方法拋出的異??赡軐儆谶@個類,也可能屬于這個類的子類。

拋出異常時請注意:

  • 如果一個方法調(diào)用了拋出檢查型異常的方法,這個方法要么處理這個異常(怎么處理標題五會詳細介紹),要么繼續(xù)傳遞這個異常(即繼續(xù)throws)。
  • 如果一個方法是覆蓋了超類中的方法,并且在超類中這個方法沒有拋出異常,那么你別無選擇,必須處理所有可能發(fā)生的檢查型異常(因為子類中的覆蓋方法拋出范圍不得超過父類)。

四、定義自己的異常類

標題三中的處理方法雖然簡便,但有一個很大的缺點:你必須找到一個合適的可能觸發(fā)的異常類別,才能將其拋出。于是我們想,可不可以自己定義一個異常類別,這樣即使我們找不到合適的異常類,也可以將其拋出?

通常讓自定義的類繼承于Exception類或者IOException類,并且按照習(xí)慣,任何異常類都至少需要包含兩個構(gòu)造器,一個是默認構(gòu)造器,另一個是包含有詳細描述信息的構(gòu)造器(方便調(diào)試)。
舉例:

class FileFormatException extends IOException//自定義異常類
{
  public FileFormatException(){}
  public FileFormarException(String gripe)
  {
   super(gripe);
  }
}

String readData(BufferedReader in) throw FileFormatException//聲明自定義的異常
{
  ...
  while(...)
  {
   if(ch == -1) 
   {
     if(n < len) throw new FileFormatException();//拋出自定義的異常
   }
  }
}

五、處理檢查型異常之方法二:try-catch-finally捕獲異常

現(xiàn)在讓我們回到引例上來:

public void read(String filename)
{
  try
  {
   var in = new FileInputStream(filename);
   int b;
   while((b = in.read()) != -1)
   {
     ...
   }
  }
  catch(IOException exception)
  {
   ...
  }
}

小知識:“如果發(fā)生了某個異常,但沒有被捕獲,程序就會終止,并在控制臺上打印一個消息,其中包括這個異常的類型和一個堆棧軌跡?!?/p>

引例中完成的是一個最簡單的 try-catch 語句,現(xiàn)在我們來分析一下不同情況下程序相應(yīng)的執(zhí)行情況:

  • 如果 try 中出現(xiàn)了一個異常,且該異常被成功捕獲(在上例中即異常類型剛好為catch中的IOException類型)。則程序會跳過 try 中其余代碼,接著執(zhí)行 catch 子句中的代碼。
  • 如果 try 中出現(xiàn)了一個異常,且該異常未被成功捕獲(即異常類型與catch中的異常類型不符)。則程序會立即退出。
  • 如果 try 中未出現(xiàn)任何異常,將不會執(zhí)行 catch 中的語句。

多 catch 捕獲多個異常:

在一個try語句塊中可以捕獲多個異常類型,并對每個異常類型使用一個單獨的 catch 子句。并且,自 Java 7之后,允許一個 catch 子句捕獲多個異常類型。

try
{
 ...
}
catch(FileNotFoundException | UnknownHostException e)//一個catch捕獲多個異常
{
 ...
}
catch(IOException e)//一個 try 語句塊中多個 catch 語句
{
 ...
}

注意:

  • 用一個catch捕獲多個異常時,異常變量隱含為final變量,因此不允許為 e 賦于不同的值。
  • 多個catch子塊存在時,由于程序是由上往下依次捕捉,不允許將父類異常寫在子類的上方。
  • catch語塊中允許再次拋出異常(throw語句)

try-catch-finally語句:

假定這樣一種情況,一個程序在 try 中使用了一些本地資源,而且這些資源必須在程序退出時進行清理。如果只用try-catch方法,那么每個catch語句中都要重復(fù)書寫清理資源的代碼,顯得非常笨重且繁瑣。現(xiàn)在,我們可以用finally語句來解決這個問題,它的特定是:不管異常有無被捕獲,finally語句中的代碼都會執(zhí)行。功能是:確保資源被清理。

示例:在finally語句中關(guān)閉輸出流

var in = new FileInputStream(...)
try
{
 //1
 可能發(fā)生異常的語句
 //2
}
catch (IOException e)
{
 //3
 展示錯誤信息
 //4
}
finally
{
 //5
 in.close();//關(guān)閉輸出流
}
//6

現(xiàn)在我們來分析一下不同情況下程序相應(yīng)的執(zhí)行情況:

  • try 中代碼未拋出異常。執(zhí)行1256。
  • try 中代碼拋出異常并且被捕獲且 catch沒有拋出異常。執(zhí)行13456。
  • try 中代碼拋出異常并且被捕獲但 catch拋出異常。執(zhí)行135。
  • try 中代碼拋出異常但未被捕獲。執(zhí)行15。

總結(jié)一下,

執(zhí)行6的條件是,走完了整個 try / catch塊。

執(zhí)行5的條件是,任何條件都會執(zhí)行。

注意:

  • 允許一個catch塊都沒有。
  • 允許try / catch / finally子塊中嵌套一個try-catch-finally塊。
  • 千萬不要在finally子塊中使用改變控制流的語句?。╮eturn,throw,break,continue)。因為finally的執(zhí)行在try之后,整個方法返回之前,因此在finally子塊中改變控制流將會覆蓋 try 中的結(jié)果。(這個結(jié)果可以是一個return值,也可以是一個異常)。

六、額外補充之try-with-Resources語句

Java中存在一個AutoCloseable接口

public interface AutoCloseable
{
  void close() throws Exception;
}

假定資源屬于一個實現(xiàn)了AutoCloseable接口的類,那么處理異常時可以不需要finally子塊。因為該資源無論是正常退出或產(chǎn)生異常,都會自動調(diào)用close方法,代替了finally子塊。

帶資源的try語句通用格式:

try(Resources res = ...)
{
  work with Resources;
}

舉例如下:

try(var in = new Scanner(...))
{
  while(in.hashNext()) System.out.println(in.next());
}//無論 try塊怎么樣退出,都會執(zhí)行 in.close();

這種方式使得代碼看起來更加簡潔。

請注意:

  • try-with-Resources語句允許有catch / finally子句。它們會在資源關(guān)閉后再執(zhí)行。

最后的最后,希望提醒大家,捕獲異常雖然方便,但會極大的延長程序運行的時間,因此,只在必要條件下使用異常。

總結(jié)

到此這篇關(guān)于一篇文章解決Java異常處理的文章就介紹到這了,更多相關(guān)Java異常處理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • SpringMVC使用MultipartFile 實現(xiàn)異步上傳方法介紹

    SpringMVC使用MultipartFile 實現(xiàn)異步上傳方法介紹

    這篇文章主要介紹了SpringMVC使用MultipartFile 實現(xiàn)異步上傳方法介紹,涉及pom依賴的添加,配置文件的修改等具體操作代碼,需要的朋友可以了解下。
    2017-09-09
  • java抓取網(wǎng)頁數(shù)據(jù)示例

    java抓取網(wǎng)頁數(shù)據(jù)示例

    要通java獲取整個網(wǎng)頁的html內(nèi)容,或者某個網(wǎng)絡(luò)文件的內(nèi)容,可以使用java提供的HttpURLConnection類來實現(xiàn)對網(wǎng)頁內(nèi)容的抓取
    2014-03-03
  • java隨機數(shù)生產(chǎn)算法實例

    java隨機數(shù)生產(chǎn)算法實例

    下面小編就為大家?guī)硪黄猨ava隨機數(shù)生產(chǎn)算法實例。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-10-10
  • java實現(xiàn)注冊登錄系統(tǒng)

    java實現(xiàn)注冊登錄系統(tǒng)

    這篇文章主要為大家詳細介紹了java實現(xiàn)注冊登錄系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • SpringBoot?容器刷新前回調(diào)ApplicationContextInitializer

    SpringBoot?容器刷新前回調(diào)ApplicationContextInitializer

    這篇文章主要為大家介紹了SpringBoot?容器刷新前回調(diào)ApplicationContextInitializer使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • 淺談Java中的橋接方法與泛型的逆變和協(xié)變

    淺談Java中的橋接方法與泛型的逆變和協(xié)變

    對應(yīng)于Java當(dāng)中,協(xié)變對應(yīng)的就是<? extends XXX>,而逆變對應(yīng)的就是<? super XXX>,本文詳細的介紹了Java中的橋接方法與泛型的逆變和協(xié)變,感興趣的可以了解一下
    2022-04-04
  • 項目為什么引入log4j而不是logback代碼

    項目為什么引入log4j而不是logback代碼

    這篇文章主要介紹了項目為什么引入log4j而不是logback代碼,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-10-10
  • RabbitMQ安裝延遲消息插件的教程(超詳細)

    RabbitMQ安裝延遲消息插件的教程(超詳細)

    RabbitMQ是一個開源的消息隊列系統(tǒng),它支持多種協(xié)議和多種語言的客戶端,為了處理消息的延遲發(fā)送或消費,RabbitMQ本身并不直接提供內(nèi)置的延遲插件,所以本文給大家介紹了RabbitMQ安裝延遲消息插件的教程,需要的朋友可以參考下
    2024-06-06
  • java文件上傳(單文件 多文件)與刪除

    java文件上傳(單文件 多文件)與刪除

    本文主要分享了java文件上傳(單文件 多文件)與刪除的示例代碼。具有很好的參考價值,下面跟著小編一起來看下吧
    2017-01-01
  • Java 類在 Tomcat 中是如何加載的(過程分析)

    Java 類在 Tomcat 中是如何加載的(過程分析)

    這篇文章主要介紹了Java 類在 Tomcat 中是如何加載的過程分析,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-07-07

最新評論

澄迈县| 海阳市| 罗平县| 景谷| 新津县| 驻马店市| 高要市| 高邑县| 思茅市| 霍林郭勒市| 金湖县| 绥阳县| 改则县| 浏阳市| 陵水| 南城县| 靖边县| 磐安县| 文登市| 珠海市| 镇宁| 康乐县| 自治县| 乐至县| 合水县| 资阳市| 富锦市| 康保县| 西平县| 阿鲁科尔沁旗| 资溪县| 镇平县| 台南县| 鹿邑县| 东宁县| 大同县| 田东县| 丹凤县| 本溪市| 宿州市| 夹江县|