您好,登錄后才能下訂單哦!
這篇文章將為大家詳細講解有關Java異常的基礎知識介紹,小編覺得挺實用的,因此分享給大家做個參考,希望大家閱讀完這篇文章后可以有所收獲。
一. 異常是什么
異常是指阻止當前方法或作用域繼續執行的問題。比如你讀取的文件不存在,數組越界,進行除法時,除數為0等都會導致異常。
一個文件找不到的異常:
public class TestException { public static void main(String[] args) throws IOException { InputStream is = new FileInputStream("jaywei.txt"); int b; while ((b = is.read()) != -1) { } } }
運行結果:
Exception in thread "main" java.io.FileNotFoundException: jaywei.txt (系統找不到指定的文件。) at java.io.FileInputStream.open0(Native Method) at java.io.FileInputStream.open(FileInputStream.java:195) at java.io.FileInputStream.<init>(FileInputStream.java:138) at java.io.FileInputStream.<init>(FileInputStream.java:93) at exception.TestException.main(TestException.java:10)
二. 異常的層次結構
從前從前,有位老人,他的名字叫Throwable,他生了兩個兒子,大兒子叫Error,二兒子叫Exception。
表示編譯時或者系統錯誤,如虛擬機相關的錯誤,OutOfMemoryError等,error是無法處理的。
代碼異常,Java程序員關心的基類型通常是Exception。它能被程序本身可以處理,這也是它跟Error的區別。
它可以分為RuntimeException(運行時異常)和CheckedException(可檢查的異常)。
常見的RuntimeException異常:
- NullPointerException 空指針異常 - ArithmeticException 出現異常的運算條件時,拋出此異常 - IndexOutOfBoundsException 數組索引越界異常 - ClassNotFoundException 找不到類異常 - IllegalArgumentException(非法參數異常)
常見的 Checked Exception 異常:
- IOException (操作輸入流和輸出流時可能出現的異常) - ClassCastException(類型轉換異常類)
● Checked Exception就是編譯器要求你必須處置的異常。
● 與之相反的是,Unchecked Exceptions,它指編譯器不要求強制處置的異常,它包括Error和RuntimeException 以及他們的子類。
三、異常處理
當異常出現后,會在堆上創建異常對象。當前的執行路徑被終止,并且從當前環境中彈出對異常對象的引用。這時候異常處理程序,使程序從錯誤狀態恢復,使程序繼續運行下去。
異常處理主要有拋出異常、捕獲異常、聲明異常。如圖:
try{ // 程序代碼 }catch(Exception e){ //Catch 塊 }finaly{ //無論如何,都會執行的代碼塊 }
我們可以通過 try...catch...
捕獲異常代碼,再通過 finaly
執行最后的操作,如關閉流等操作。
除了 try...catch...
捕獲異常,我們還可以通過throws聲明拋出異常。
當你定義了一個方法時,可以用 throws
關鍵字聲明。使用了 throws
關鍵字表明,該方法不處理異常,而是把異常留給它的調用者處理。是不是覺得TA不負責任?
哈哈,看一下demo吧
//該方法通過throws聲明了IO異常。 private void readFile() throws IOException { InputStream is = new FileInputStream("jaywei.txt"); int b; while ((b = is.read()) != -1) { } }
從方法中聲明拋出的任何異常都必須使用throws子句。
throw關鍵字作用是拋出一個 Throwable
類型的異常,它一般出現在函數體中。在異常處理中,try語句要捕獲的是一個異常對象,其實此異常對象也可以自己拋出。
例如拋出一個 RuntimeException 類的異常對象:
throw new RuntimeException(e);
任何Java代碼都可以通過 Java 的throw語句拋出異常。
● 非檢查異常(Error、RuntimeException 或它們的子類)不可使用 throws 關鍵字來聲明要拋出的異常。
● 一個方法出現編譯時異常,就需要 try-catch/ throws 處理,否則會導致編譯錯誤。
四、try-catch-finally-return執行順序
try-catch-finally-return 執行描述
● 如果不發生異常,不會執行catch部分。
● 不管有沒有發生異常,finally都會執行到。
● 即使try和catch中有return時,finally仍然會執行
● finally是在return后面的表達式運算完后再執行的。(此時并沒有返回運算后的值,而是先把要返回的值保存起來,若finally中無return,則不管finally中的代碼怎么樣,返回的值都不會改變,仍然是之前保存的值),該情況下函數返回值是在finally執行前確定的)
● finally部分就不要return了,要不然,就回不去try或者catch的return了。
看一個例子
public static void main(String[] args) throws IOException { System.out.println("result:" + test()); } private static int test() { int temp = 1; try { System.out.println("start execute try,temp is:"+temp); return ++temp; } catch (Exception e) { System.out.println("start execute catch temp is: "+temp); return ++temp; } finally { System.out.println("start execute finally,temp is:" + temp); ++temp; } }
運行結果:
start execute try,temp is:1 start execute finally,temp is:2 result:2
分析
● 先執行try部分,輸出日志,執行 ++temp
表達式,temp變為2,這個值被保存起來。
● 因為沒有發生異常,所以catch代碼塊跳過。
● 執行finally代碼塊,輸出日志,執行 ++temp
表達式.
● 返回try部分保存的值2.
五、Java異常類的幾個重要方法
先來喵一眼異常類的所有方法,如下圖:
Returns the detail message string of this throwable.
getMessage會返回Throwable的 detailMessage
屬性,而 detailMessage
就表示發生異常的詳細消息描述。
舉個例子, FileNotFoundException
異常發生時,這個 detailMessage
就包含這個找不到文件的名字。
Creates a localized description of this throwable.Subclasses may override this method in order to produce alocale-specific message. For subclasses that do not override thismethod, the default implementation returns the same result as getMessage()
throwable的本地化描述。子類可以重寫此方法,以生成特定于語言環境的消息。對于不覆蓋此方法的子類,默認實現返回與相同的結果 getMessage()。
Returns the cause of this throwable or null if thecause is nonexistent or unknown.
返回此可拋出事件的原因,或者,如果原因不存在或未知,返回null。
Prints this throwable and its backtrace to thestandard error stream. The first line of output contains the result of the toString() method for this object.Remaining lines represent data previously recorded by the method fillInStackTrace().
該方法將堆棧跟蹤信息打印到標準錯誤流。
輸出的第一行,包含此對象toString()方法的結果。剩余的行表示,先前被方法fillInStackTrace()記錄的數據。如下例子:
java.lang.NullPointerException at MyClass.mash(MyClass.java:9) at MyClass.crunch(MyClass.java:6) at MyClass.main(MyClass.java:3)
六、自定義異常
自定義異常通常是定義一個繼承自 Exception 類的子類。
那么,為什么需要自定義異常?
● Java提供的異常體系不可能預見所有的錯誤。
● 業務開發中,使用自定義異常,可以讓項目代碼更加規范,也便于管理。
下面是我司自定義異常類的一個簡單demo
public class BizException extends Exception { //錯誤信息 private String message; //錯誤碼 private String errorCode; public BizException() { } public BizException(String message, String errorCode) { this.message = message; this.errorCode = errorCode; } @Override public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public String getErrorCode() { return errorCode; } public void setErrorCode(String errorCode) { this.errorCode = errorCode; } }
跑個main方測試一下
public class TestBizException { public static void testBizException() throws BizException { System.out.println("throwing BizException from testBizException()"); throw new BizException("100","哥,我錯了"); } public static void main(String[] args) { try { testBizException(); } catch (BizException e) { System.out.println("自己定義的異常"); e.printStackTrace(); } } }
運行結果:
exception.BizException: 100 throwing BizException from testBizException() 自己定義的異常 at exception.TestBizException.testBizException(TestBizException.java:7) at exception.TestBizException.main(TestBizException.java:12)
七、Java7 新的 try-with-resources語句
try-with-resources,是Java7提供的一個新功能,它用于自動資源管理。
● 資源是指在程序用完了之后必須要關閉的對象。
● try-with-resources保證了每個聲明了的資源在語句結束的時候會被關閉
● 什么樣的對象才能當做資源使用呢?只要實現了java.lang.AutoCloseable接口或者java.io.Closeable接口的對象,都OK。
在 try-with-resources
出現之前
try{ //open resources like File, Database connection, Sockets etc } catch (FileNotFoundException e) { // Exception handling like FileNotFoundException, IOException etc }finally{ // close resources }
Java7, try-with-resources
出現之后,使用資源實現
try(// open resources here){ // use resources } catch (FileNotFoundException e) { // exception handling } // resources are closed as soon as try-catch block is executed.
Java7使用資源demo
public class Java7TryResourceTest { public static void main(String[] args) { try (BufferedReader br = new BufferedReader(new FileReader( "C:/jaywei.txt"))) { System.out.println(br.readLine()); } catch (IOException e) { e.printStackTrace(); } } }
使用了 try-with-resources
的好處
● 代碼更加優雅,行數更少。
● 資源自動管理,不用擔心內存泄漏問題。
八、異常鏈
我們常常會想要在捕獲一個異常后拋出另一個異常,并且希望把原始異常的信息保存下來,這被稱為異常鏈。
throw 拋出的是一個新的異常信息,這樣會導致原有的異常信息丟失。在JDk1.4以前,程序員必須自己編寫代碼來保存原始異常信息。現在所有 Throwable
子類在構造器中都可以接受一個 cause(異常因由)
對象作為參數。
這個 cause
就用來表示原始異常,這樣通過把原始異常傳遞給新的異常,使得即使當前位置創建并拋出了新的異常,也能通過這個異常鏈追蹤到異常最初發生的位置。
使用方式如下:
public class TestChainException { public void readFile() throws MyException{ try { InputStream is = new FileInputStream("jay.txt"); Scanner in = new Scanner(is); while (in.hasNext()) { System.out.println(in.next()); } } catch (FileNotFoundException e) { //e 保存異常信息 throw new MyException("文件在哪里呢", e); } } public void invokeReadFile() throws MyException{ try { readFile(); } catch (MyException e) { //e 保存異常信息 throw new MyException("文件找不到", e); } } public static void main(String[] args) { TestChainException t = new TestChainException(); try { t.invokeReadFile(); } catch (MyException e) { e.printStackTrace(); } } } //MyException 構造器 public MyException(String message, Throwable cause) { super(message, cause); }
運行結果:
我們可以看到異常信息有保存下來的,如果把cause(也就是FileNotFoundException 的e)去掉呢,看一下運行結果:
可以發現,少了 Throwablecause
,原始異常信息不翼而飛了。
九、異常匹配
拋出異常的時候,異常處理系統會按照代碼的書寫順序找出"最近"的處理程序。找到匹配的處理程序之后,它就認為異常將得到處理,然后就不再繼續查找。
查找的時候并不要求拋出的異常同處理程序的異常完全匹配。派生類的對象也可以配備其基類的處理程序
看demo
package exceptions; //: exceptions/Human.java // Catching exception hierarchies. class Annoyance extends Exception {} class Sneeze extends Annoyance {} public class Human { public static void main(String[] args) { // Catch the exact type: try { throw new Sneeze(); } catch(Sneeze s) { System.out.println("Caught Sneeze"); } catch(Annoyance a) { System.out.println("Caught Annoyance"); } // Catch the base type: try { throw new Sneeze(); } catch(Annoyance a) { System.out.println("Caught Annoyance"); } } }
運行結果:
catch(Annoyance a)會捕獲Annoyance以及所有從它派生的異常。捕獲基類的異常,就可以匹配所有派生類的異常
try { throw new Sneeze(); } catch(Annoyance a) { } catch(Sneeze s) { //這句編譯器會報錯,因為異常已由前面catch子句處理 }
十、Java常見異常
NullPointerException
空指針異常,最常見的一個異常類。簡言之,調用了未經初始化的對象或者是不存在的對象,就會產生該異常。
ArithmeticException
算術異常類,程序中出現了除數為0這樣的運算,就會出現這樣的異常。
ClassCastException
類型強制轉換異常,它是JVM在檢測到兩個類型間轉換不兼容時引發的運行時異常。
ArrayIndexOutOfBoundsException
數組下標越界異常,跟數組打交道時,需要注意一下這個異常。
FileNotFoundException
文件未找到異常,一般是要讀或者寫的文件,找不到,導致該異常。
SQLException
操作數據庫異常,它是Checked Exception(檢查異常);
IOException
IO異常,一般跟讀寫文件息息相關,它也是Checked Exception(檢查異常)。平時讀寫文件,記得IO流關閉!
NoSuchMethodException
方法未找到異常
NumberFormatException
字符串轉換為數字異常
總結
這個總結獨辟蹊徑,以幾道經典異常面試題結束吧,以幫助大家復習一下,嘻嘻。
● java 異常有哪幾種,特點是什么?(知識點二可答)
● 什么是Java中的異常?(知識點一可答)
● error和exception有什么區別?(知識點二可答)
● 什么是異常鏈?(知識點八可答)
● try-catch-finally-return執行順序(知識點四可答)
● 列出常見的幾種RunException (知識點二可答)
● Java異常類的重要方法是什么?(知識點五可答)
● error和exception的區別,CheckedException,RuntimeException的區別。(知識點二可答)
● 請列出5個運行時異常。(知識點二可答)
● Java 7 新的 try-with-resources 語句(知識點七可答)
● 怎么自定義異常?(知識點六可答)
● 說一下常見異常以及產生原因(知識點十可答)
● 談談異常匹配(知識點九可答)
● 談談異常處理(知識點三可答)
關于Java異常的基礎知識介紹就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。