什麼是異常?
結構不良的程式碼不能執行,這是Java的基本理念。
發現錯誤的理想時機是在編譯期。然而,編譯器並不能發現所有的錯誤,剩下的問題就需要在程式執行時解決。這就需要錯誤能透過某種方式,把適當的訊息 傳遞給特定的接收者處理。
Java中的異常處理的目的在於透過使用少量的程式碼來簡化大型、可靠的程式的生成,透過此方式讓你的應用程式中沒有未處理的錯誤,而且它還帶來了一個明顯的好處:降低錯誤處理程式碼的複雜度。
異常,根據字面理解,有意外之意。把它置於程式碼層面來理解,即阻止了當前方法或作用域繼續執行。異常是導致程式無法在其預期的執行中運行的事件。異常有三種類型-檢查異常、錯誤和運行時異常。
在Java中,異常被當作物件來處理,其基底類別是Throwable。
Java中的例外類型
Java從Throwable直接衍生出Exception和Error。其中Exception是可以拋出的基本類型,在Java類別庫、方法以及執行階段故障中都可能拋出Exception型異常。 Exception表示可以恢復的異常,是編譯器可以捕捉到的;Error表示編譯時和系統錯誤,表示系統在運行期間出現了嚴重的錯誤,屬於不可恢復的錯誤,由於這屬於JVM層次的嚴重錯誤,因此這種錯誤會導致程式終止執行。 Exception又分為檢查異常和執行時期異常。
異常類別的結構層次圖如下:
典型的RuntimeException(運行時異常)包含NullPointerException, ClassCastException(型別轉換例外),IndexOutOfBoundsException(越界異常), IllegalArgumentException(非法參數異常),ArrayStoreException(數組存儲異常),AruthmeticException(算術異常),BufferOverflowException(緩衝區溢出異常)等;
RuntimeException(檢查異常)包括IOException, SQLException,InterruptedException(中斷異常-呼叫執行緒睡眠時候),NumberFormatException(數字格式化異常)等。
而依照編譯器檢查方式劃分,異常又可以分為檢查型異常(CheckedException)和非檢查型異常 (UncheckedException)。 Error和RuntimeException合起來稱為UncheckedException,之所以這麼稱呼,是因為編譯器不檢查方法是否處理或拋出這兩種類型的異常,因此編譯期間出現這種類型的異常也不會報錯,預設由虛擬機提供處理方式。除了Error 和RuntimeException這兩種類型的異常外,其它的異常都稱為Checked異常。
Java如何處理例外
#1、try-catch, try-finally, try-catch-finally
#對於checked類型異常,我們要麼對它進行處理,要麼在方法頭使用throws拋出。
public static void createFile() throws IOException{ File file = new File("C:/test.txt"); if(!file.exists()){ file.createNewFile(); } } public static void main(String[] args) { try { createFile(); } catch (IOException ex) { // handle exception here } }
關於catch需要注意的幾點:
1)、參數的例外類型必須是Throwable類別或其子類別。
2)、從上往下的catch語句,其參數型別必須依照從子類別到父類別順序,因為一旦配對到一個型別,就會忽略往後的catch。例如IOException必須放到Exception前面,否則編譯器會報錯。
3)、可以有一個或多個catch語句,甚至如果有finally語句的情況下,可以沒有catch語句,如try-finally。
想要捕獲多個異常,可以使用多個catch語句,JDK7以後提供了另一種方式:多重捕獲(multi-catch)。
try{ // other code } catch (IOException | SQLException ex) { throw ex; }
4)、不要忽略異常。空的catch區塊會使異常達不到應有的目的,除非諸如關閉FileInputStream的時候,因為你還沒有改變文件的狀態,因此不必執行任何恢復動作,並且已經從文件中讀取到所需的信息,因此不用終止正在進行的操作。
關於finally需要注意的幾點:
1)、finally中的程式碼總是會被執行,除非在執行try或catch語句時虛擬機器退出(System.exit(1 ))。
2)、finally區塊可以做一些資源清理工作,例如關閉檔案、關閉遊標等操作。
3)、finally區塊不是必須的。
另外,如果在try和finally區塊中都執行了return語句,最後回傳的將會是finally中的return值。
2、異常鏈
常常想要在捕获一个异常后抛出另外一个异常,并且希望把原始异常信息保存下来,这就是异常链。在JDK1.4以后,Throwable子类在构造器 中可以接受一个cause对象作为参数,表示原始异常,通过这样把原始异常传递给新的异常,使得即使在当前位置创建并抛出了新的异常,也能通过这个异常链 追踪到异常最初发生的位置。
但在Throwable子类中,只有Error, Exception, RuntimeException三类异常类提供了带cause参数的构造器,其它类型的异常则需要通过initCause()方法。例如定义了CustomException类,可以这样使用:
CustomException cmex = new CustomException(); cmex.initCause(new NullPointerException); throw cmex;
这样一来,CustomException继承自Exception或RuntimeException,就属于自定义异常了。
一般来说,自定义异常的作用有以下情形:
1)、将检查型异常转换为非检查型异常。
2)、在产生异常时封装上下文信息、定义异常码、收集环境对象,有利于信息的传递。
异常使用指南
1、在知道该如何处理的情况下才捕获异常。
2、自定义异常类型,用以封装所有的检查型异常。
3、在程序的边界进行异常捕获。如服务端相应客户端的请求,在出口处catch内部有可能产生的异常,并统一throw一个封装过的异常给客户端,免得暴露服务端敏感信息。
4、只针对异常的情况才使用异常。不要在所有的代码中习惯性地使用try-catch,因为这会影响性能。
5、抛出与抽象相对的异常。如果方法抛出的异常与它执行的任务没有明显的联系,这种情形会使人不知所措。为了避免这个问题,更高层的实现应该捕获 低层的异常,同时抛出可以按照高层抽象进行解释的异常,这种做法被称为异常转译(exception translation),如下:
try{ // use lower-level abstraction to do our bidding } catch(LowerLevelException ex){ throw new HigherLevelException(...); }
另外一种特殊的异常转译称为异常链,上面已作描述。如果低层的异常对于调试导致高层异常的问题非常有帮助,使用异常链就很合适。高层的异常提供访问方法(Throwable.getCause)来获得低层的异常。
6、每个方法抛出的异常要有文档描述。利用Javadoc的@throws标记,记录抛出每个异常的条件。如果一个方法可能抛出多个异常,不要使 用这些异常类的某个超类。如不要声明一个方法“throws Exception”或“throws Throwable”,这将没有任何指导信息。
以上是java什麼是異常?的詳細內容。更多資訊請關注PHP中文網其他相關文章!