溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java中的異常與錯誤如何處理

發(fā)布時間:2021-12-01 11:29:01 來源:億速云 閱讀:140 作者:iii 欄目:編程語言

這篇文章主要介紹“Java中的異常與錯誤如何處理”,在日常操作中,相信很多人在Java中的異常與錯誤如何處理問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java中的異常與錯誤如何處理”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

異常與錯誤:

異常:

在Java中程序的錯誤主要是語法錯誤和語義錯誤,一個程序在編譯和運行時出現的錯誤我們統一稱之為異常,它是VM(虛擬機)通知你的一種方式,通過這種方式,VM讓你知道,你(開發(fā)人員)已經犯了個錯誤,現在有一個機會來修改它。Java中使用異常類來表示異常,不同的異常類代表了不同的異常。但是在Java中所有的異常都有一個基類,叫做Exception。

錯誤:

它指的是一個合理的應用程序不能截獲的嚴重的問題。大多數都是反常的情況。錯誤是VM的一個故障(雖然它可以是任何系統級的服務)。所以,錯誤是很難處理的,一般的開發(fā)人員(當然不是你)是無法處理這些錯誤的,比如內存溢出。  和異常一樣,在Java中用錯誤類來表示錯誤,不同的錯誤類代表了不同的錯誤。 但是在Java中所有的錯誤都有一個基類,叫做Error。

綜上,我們可以知道異常和錯誤最本質的區(qū)別就是異常能被開發(fā)人員處理而錯誤時系統本來自帶的,一般無法處理也不需要我們程序員來處理。

1.一個異常是在一個程序執(zhí)行過程中出現的一個事件,它中斷了正常指令的運行

2.錯誤,偏離了可接受的代碼行為的一個動作或實例

異常的結構分類:

1、運行時異常(未檢查異常)

2、編譯時異常(已檢查異常)

運行異常即是RuntimeException;其余的全部為編譯異常

在Java中異常Exception和錯誤Error有個共同的父類Throwable。

Error Exception

runtimeException幾個子類

1、 java.lang.ArrayIndexOutOfBoundsException

數組索引越界異常。當對數組的索引值為負數或大于等于數組大小時拋出。

2、java.lang.ArithmeticException

算術條件異常。譬如:整數除零等。

3、java.lang.NullPointerException

空指針異常。當應用試圖在要求使用對象的地方使用了null時,拋出該異常。譬如:調用null對象的實例方法、訪問null對象的

屬性、計算null對象的長度、使用throw語句拋出null等等

4、java.lang.ClassNotFoundException

找不到類異常。當應用試圖根據字符串形式的類名構造類,而在遍歷CLASSPAH之后找不到對應名稱的class文件時,拋出

該異常。

對異常的處理:

try{}catch{}

try{}catch{}finally{}無論有無異常finally代碼塊都會被執(zhí)行

try{}finally{}也是可以組合使用的但是catch{}finally{}不可以

注意:在繼承關系中,子類覆蓋父類的方法,拋出異常的范圍不能比父類更寬泛

異常的使用

在異常的使用這一部分主要是演示代碼,都是我們平常寫代碼的過程中會遇到的(當然只是一小部分),拋磚引玉嗎!

例1. 這個例子主要通過兩個方法對比來演示一下有了異常以后代碼的執(zhí)行流程。

public static void testException1() {      int[] ints = new int[] { 1, 2, 3, 4 };      System.out.println("異常出現前");      try {           System.out.println(ints[4]);           System.out.println("我還有幸執(zhí)行到嗎");// 發(fā)生異常以后,后面的代碼不能被執(zhí)行      } catch (IndexOutOfBoundsException e) {           System.out.println("數組越界錯誤");      }      System.out.println("異常出現后"); }  /*output: 異常出現前 數組越界錯誤 常出現后 */  public static void testException2() {      int[] ints = new int[] { 1, 2, 3, 4 };      System.out.println("異常出現前");      System.out.println(ints[4]);      System.out.println("我還有幸執(zhí)行到嗎");// 發(fā)生異常以后,他后面的代碼不能被執(zhí)行 }

首先指出例子中的不足之處,IndexOutofBoundsException是一個非受檢異常,所以不用try…catch…顯示捕捉,但是我的目的是對同一個異常用不同的處理方式,看它會有什么不同的而結果(這里也就只能用它將就一下了)。異常出現時***個方法只是跳出了try塊,但是它后面的代碼會照樣執(zhí)行的。但是第二種就不一樣了直接跳出了方法,比較強硬。從***個方法中我們看到,try…catch…是一種”事務性”的保障,它的目的是保證程序在異常的情況下運行完畢,同時它還會告知程序員程序中出錯的詳細信息(這種詳細信息有時要依賴于程序員設計)。

例2. 重新拋出異常

public class Rethrow {      public static void readFile(String file) throws FileNotFoundException {      try {           BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));      } catch (FileNotFoundException e) {           e.printStackTrace();           System.err.println("不知道如何處理該異?;蛘吒静幌胩幚硭遣蛔鎏幚碛植缓线m,這是重新拋出異常交給上一級處理");           //重新拋出異常           throw e;      } } public static void printFile(String file) {      try {           readFile(file);      } catch (FileNotFoundException e) {           e.printStackTrace();      } }      public static void main(String[] args) {           printFile("D:/file");      } }

異常的本意是好的,讓我們試圖修復程序,但是現實中我們修復的幾率很小,我們很多時候就是用它來記錄出錯的信息。如果你厭倦了不停的處理異常,重新拋出異常對你來說可能是一個很好的解脫。原封不動的把這個異常拋給上一級,拋給調用這個方法的人,讓他來費腦筋吧。這樣看來,java異常(當然指的是受檢異常)又給我們平添很多麻煩,盡管它的出發(fā)點是好的。

例3. 異常鏈的使用及異常丟失

ExceptionA,ExceptionB,ExceptionC public class ExceptionA extends Exception {      public ExceptionA(String str) {           super();      } } public class ExceptionB extends ExceptionA {      public ExceptionB(String str) {           super(str);      } } public class ExceptionC extends ExceptionA {      public ExceptionC(String str) {           super(str);      } }

異常丟失的情況:

public class NeverCaught {      static void f() throws ExceptionB{           throw new ExceptionB("exception b");      }      static void g() throws ExceptionC {           try {                f();           } catch (ExceptionB e) {                ExceptionC c = new ExceptionC("exception a");                throw c;           }      }      public static void main(String[] args) {           try {                g();           } catch (ExceptionC e) {                e.printStackTrace();           }      } } /* exception.ExceptionC at exception.NeverCaught.g(NeverCaught.java:12) at exception.NeverCaught.main(NeverCaught.java:19) */

為什么只是打印出來了ExceptionC而沒有打印出ExceptionB呢?這個還是自己分析一下吧!

上面的情況相當于少了一種異常,這在我們排錯的過程中非常的不利。那我們遇到上面的情況應該怎么辦呢?這就是異常鏈的用武之地:保存異常信息,在拋出另外一個異常的同時不丟失原來的異常。

public class NeverCaught {      static void f() throws ExceptionB{            throw new ExceptionB("exception b");      }      static void g() throws ExceptionC {           try {                 f();           } catch (ExceptionB e) {                 ExceptionC c = new ExceptionC("exception a");                 //異常連                 c.initCause(e);                 throw c;           }      }      public static void main(String[] args) {           try {                 g();           } catch (ExceptionC e) {                 e.printStackTrace();           }      } } /* exception.ExceptionC at exception.NeverCaught.g(NeverCaught.java:12) at exception.NeverCaught.main(NeverCaught.java:21) Caused by: exception.ExceptionB at exception.NeverCaught.f(NeverCaught.java:5) at exception.NeverCaught.g(NeverCaught.java:10) ... 1 more */

這個異常鏈的特性是所有異常均具備的,因為這個initCause()方法是從Throwable繼承的。

例4. 清理工作

清理工作對于我們來說是必不可少的,因為如果一些消耗資源的操作,比如IO,JDBC。如果我們用完以后沒有及時正確的關閉,那后果會很嚴重,這意味著內存泄露。異常的出現要求我們必須設計一種機制不論什么情況下,資源都能及時正確的清理。這就是finally。

public void readFile(String file) {      BufferedReader reader = null;      try {            reader = new BufferedReader(new InputStreamReader(new FileInputStream(file)));            // do some other work      } catch (FileNotFoundException e) {            e.printStackTrace();      } finally {            try {                  reader.close();            } catch (IOException e) {                  e.printStackTrace();            }      } }

例子非常的簡單,是一個讀取文件的例子。這樣的例子在JDBC操作中也非常的常見。(所以,我覺得對于資源的及時正確清理是一個程序員的基本素質之一。)

Try…finally結構也是保證資源正確關閉的一個手段。如果你不清楚代碼執(zhí)行過程中會發(fā)生什么異常情況會導致資源不能得到清理,那么你就用try對這段”可疑”代碼進行包裝,然后在finally中進行資源的清理。舉一個例子:

public void readFile() {      BufferedReader reader = null;      try {            reader = new BufferedReader(new InputStreamReader(new FileInputStream("file")));            // do some other work            //close reader            reader.close();      } catch (FileNotFoundException e) {            e.printStackTrace();      } catch (IOException e) {            e.printStackTrace();      } }

我們注意一下這個方法和上一個方法的區(qū)別,下一個人可能習慣更好一點,及早的關閉reader。但是往往事與愿違,因為在reader.close()以前異常隨時可能發(fā)生,這樣的代碼結構不能預防任何異常的出現。因為程序會在異常出現的地方跳出,后面的代碼不能執(zhí)行(這在上面應經用實例證明過)。這時我們就可以用try…finally來改造:

public void readFile() {      BufferedReader reader = null;      try {            try {                  reader = new BufferedReader(new InputStreamReader(new FileInputStream("file")));                  // do some other work                  // close reader            } finally {                  reader.close();            }       } catch (FileNotFoundException e) {            e.printStackTrace();       } catch (IOException e) {            e.printStackTrace();       } }

及早的關閉資源是一種良好的行為,因為時間越長你忘記關閉的可能性越大。這樣在配合上try…finally就保證萬無一失了(不要嫌麻煩,java就是這么中規(guī)中矩)。

再說一種情況,假如我想在構造方法中打開一個文件或者創(chuàng)建一個JDBC連接,因為我們要在其他的方法中使用這個資源,所以不能在構造方法中及早的將這個資源關閉。那我們是不是就沒轍了呢?答案是否定的??匆幌孪旅娴睦樱?/p>

public class ResourceInConstructor {      BufferedReader reader = null;      public ResourceInConstructor() {           try {                 reader = new BufferedReader(new InputStreamReader(new FileInputStream("")));           } catch (FileNotFoundException e) {                 e.printStackTrace();           }      }      public void readFile() {           try {                  while(reader.readLine()!=null) {                       //do some work                  }           } catch (IOException e) {                  e.printStackTrace();           }       }       public void dispose() {            try {                 reader.close();            } catch (IOException e) {                 e.printStackTrace();            }       } }

到此,關于“Java中的異常與錯誤如何處理”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續(xù)學習更多相關知識,請繼續(xù)關注億速云網站,小編會繼續(xù)努力為大家?guī)砀鄬嵱玫奈恼拢?/p>

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI