程序錯誤分爲三種:1,編譯錯誤;2,運行時錯誤;3,邏輯錯誤。 編譯錯誤是由於程序沒有遵循語法規則,編譯程序可以本身發現而且提示咱們錯誤的緣由和位置,這個也是你們在剛接觸編程語言最常遇到的問題。 運行時錯誤是由於程序在執行時,運行環境發現了不能執行的操做。 邏輯錯誤是由於程序沒有按照預期的邏輯順序執行。異常也就是指程序運行時發生錯誤,而異常處理就是對這些錯誤進行處理和控制。
Java異常類層次結構圖:
java
在 Java 中,全部的異常都有一個共同的祖先java.lang包中的 **Throwable類**。Throwable: 有兩個重要的子類:**Exception(異常)**和 **Error(錯誤)**,兩者都是 Java 異常處理的重要子類,各自都包含大量子類。
<font color="#99FF33">Error(錯誤):是程序沒法處理的錯誤</font>,表示運行應用程序中較嚴重問題。大多數錯誤與代碼編寫者執行的操做無關,而表示代碼運行時 JVM(Java 虛擬機)出現的問題。例如,Java虛擬機運行錯誤(Virtual MachineError),當 JVM 再也不有繼續執行操做所需的內存資源時,將出現 OutOfMemoryError。這些異常發生時,Java虛擬機(JVM)通常會選擇線程終止。程序員
這些錯誤表示故障發生於虛擬機自身、或者發生在虛擬機試圖執行應用時,如Java虛擬機運行錯誤(Virtual MachineError)、類定義錯誤(NoClassDefFoundError)等。這些錯誤是不可查的,由於它們在應用程序的控制和處理能力之 外,並且絕大多數是程序運行時不容許出現的情況。對於設計合理的應用程序來講,即便確實發生了錯誤,本質上也不該該試圖去處理它所引發的異常情況。在 Java中,錯誤經過Error的子類描述。面試
<font color="#99FF33">Exception(異常):是程序自己能夠處理的異常。</font>Exception 類有一個重要的子類 RuntimeException。RuntimeException 異常由Java虛擬機拋出。NullPointerException(要訪問的變量沒有引用任何對象時,拋出該異常)、ArithmeticException(算術運算異常,一個整數除以0時,拋出該異常)和 ArrayIndexOutOfBoundsException (下標越界異常)。數據庫
<font color="#99FF33">注意:異常和錯誤的區別:異常能被程序自己能夠處理,錯誤是沒法處理。</font>編程
一般,Java的異常(包括Exception和Error)分爲可查的異常(checked exceptions)和不可查的異常(unchecked exceptions)。數組
可查異常(編譯器要求必須處置的異常):正確的程序在運行中,很容易出現的、情理可容的異常情況。可查異常雖然是異常情況,但在必定程度上它的發生是能夠預計的,並且一旦發生這種異常情況,就必須採起某種方式進行處理。安全
除了RuntimeException及其子類之外,其餘的Exception類及其子類都屬於可查異常。這種異常的特色是Java編譯器會檢查它,也就是說,當程序中可能出現這類異常,要麼用try-catch語句捕獲它,要麼用throws子句聲明拋出它,不然編譯不會經過。微信
不可查異常(編譯器不要求強制處置的異常):包括運行時異常(RuntimeException與其子類)和錯誤(Error)。編程語言
Exception 這種異常分兩大類運行時異常和非運行時異常(編譯異常)。程序中應當儘量去處理這些異常。學習
運行時異常:都是RuntimeException類及其子類異常,如NullPointerException(空指針異常)、IndexOutOfBoundsException(下標越界異常)等,這些異常是不檢查異常,程序中能夠選擇捕獲處理,也能夠不處理。這些異常通常是由程序邏輯錯誤引發的,程序應該從邏輯角度儘量避免這類異常的發生。
運行時異常的特色是Java編譯器不會檢查它,也就是說,當程序中可能出現這類異常,即便沒有用try-catch語句捕獲它,也沒有用throws子句聲明拋出它,也會編譯經過。
非運行時異常 (編譯異常):是RuntimeException之外的異常,類型上都屬於Exception類及其子類。從程序語法角度講是必須進行處理的異常,若是不處理,程序就不能編譯經過。如IOException、SQLException等以及用戶自定義的Exception異常,通常狀況下不自定義檢查異常。
public string getMessage():返回異常發生時的詳細信息
public string toString():返回異常發生時的簡要描述
public string getLocalizedMessage():返回異常對象的本地化信息。使用Throwable的子類覆蓋這個方法,能夠聲稱本地化信息。若是子類沒有覆蓋該方法,則該方法返回的信息與getMessage()返回的結果相同
public void printStackTrace():在控制檯上打印Throwable對象封裝的異常信息
一、 java.lang.ArrayIndexOutOfBoundsException 數組索引越界異常。當對數組的索引值爲負數或大於等於數組大小時拋出。 二、java.lang.ArithmeticException 算術條件異常。譬如:整數除零等。 三、java.lang.NullPointerException 空指針異常。當應用試圖在要求使用對象的地方使用了null時,拋出該異常。譬如:調用null對象的實例方法、訪問null對象的屬性、計算null對象的長度、使用throw語句拋出null等等 四、java.lang.ClassNotFoundException 找不到類異常。當應用試圖根據字符串形式的類名構造類,而在遍歷CLASSPAH以後找不到對應名稱的class文件時,拋出該異常。 五、java.lang.NegativeArraySizeException 數組長度爲負異常 六、java.lang.ArrayStoreException 數組中包含不兼容的值拋出的異常 七、java.lang.SecurityException 安全性異常 八、java.lang.IllegalArgumentException 非法參數異常
IOException:操做輸入流和輸出流時可能出現的異常。 EOFException 文件已結束異常 FileNotFoundException 文件未找到異常
ClassCastException 類型轉換異常類 ArrayStoreException 數組中包含不兼容的值拋出的異常 SQLException 操做數據庫異常類 NoSuchFieldException 字段未找到異常 NoSuchMethodException 方法未找到拋出的異常 NumberFormatException 字符串轉換爲數字拋出的異常 StringIndexOutOfBoundsException 字符串索引超出範圍拋出的異常 IllegalAccessException 不容許訪問某類異常 InstantiationException 當應用程序試圖使用Class類中的newInstance()方法建立一個類的實例,而指定的類對象沒法被實例化時,拋出該異常
在 Java 應用程序中,異常處理機制爲:拋出異常,捕捉異常。
任何代碼都有可能發生系統錯誤(Error)和運行時錯誤(RunrimeException),所以在方法聲明時,Java系統不要求顯示的聲明Error和RuntimeException兩種異常類(系統隱含的聲明瞭這兩種異常類),可是,能夠在方法體中拋出這兩種異常對象。須要注意的是:若是要在方法體中拋出其它異常,必須在方法頭聲明這種異常類。
,聲明異常類的格式:
在方法頭中使用throws關鍵字,例如:
public void myThod throws IOException //這裏聲明的異常類是:IOException.
關鍵字throws指出方法myThod在執行時可能拋出IOException異常(對象)。若是方法執行時可能拋出多種異常,就能夠像實現多個接口的同樣,將異常類之間用逗號隔開,例如:
public void myThod throws Exception1, Exception2....... ExceptionnN
拋出異常對象的格式
在方法頭中聲明瞭異常類後,就應該在方法體中拋出一個與方法頭名中聲明的異常類相一致的對象。例如:
Throw new TheException();//拋出異常
或
TheException ex=new TheException();
Throw ex;//拋出異常對象ex
注意:聲明異常類的關鍵字是throws,拋出異常對象的關鍵字是throw
try { // 可能會發生異常的程序代碼 } catch (Type1 id1){ // 捕獲並處置try拋出的異常類型Type1 } catch (Type2 id2){ //捕獲並處置try拋出的異常類型Type2 }
注意一個try語句後面能夠跟不少catch語句,catch語句被稱爲異常處理器。關鍵詞try後的一對大括號將一塊可能發生異常的代碼包起來,稱爲監控區域。Java方法在運行過程當中出現異常,則建立異常對象。將異常拋出監控區域之 外,由Java運行時系統試圖尋找匹配的catch子句以捕獲異常。如有匹配的catch子句,則運行其異常處理代碼,try-catch語句結束。
匹配的原則是:若是拋出的異常對象屬於catch子句的異常類,或者屬於該異常類的子類,則認爲生成的異常對象與catch塊捕獲的異常類型相匹配
例1 捕捉throw語句拋出的「除數爲0」異常。
public class TestException { public static void main(String[] args) { int a = 6; int b = 0; try { // try監控區域 if (b == 0) throw new ArithmeticException(); // 「除數爲0」等ArithmeticException,是RuntimException的子類。而運行時異常將由運行時系統自動拋出,不須要使用throw語句,這裏把throw new ArithmeticException()去掉也是不影響運行結果的。 System.out.println("a/b的值是:" + a / b); } catch (ArithmeticException e) { // catch捕捉異常 System.out.println("程序出現異常,變量b不能爲0。"); } System.out.println("程序正常結束。"); } }
運行結果:
在例1中 try監控區域經過if語句進行判斷,當「除數爲0」的錯誤條件成立時引起ArithmeticException異常,建立 ArithmeticException異常對象,並由throw語句將異常拋給Java運行時系統,由系統尋找匹配的異常處理器catch並運行相應異 常處理代碼,打印輸出「程序出現異常,變量b不能爲0。」try-catch語句結束,繼續程序流程。 <font color="#00BBFF"> 須要注意的是,一旦某個catch捕獲到匹配的異常類型,將進入異常處理代碼。一經處理結束,就意味着整個try-catch語句結束。其餘的catch子句再也不有匹配和捕獲異常類型的機會。</font>
<font color="#00BBFF"> Java經過異常類描述異常類型,異常類的層次結構如圖1所示。對於有多個catch子句的異常程序而言,應該儘可能將捕獲底層異常類的catch子 句放在前面,同時儘可能將捕獲相對高層的異常類的catch子句放在後面。不然,捕獲底層異常類的catch子句將可能會被屏蔽。</font>
<font color="#0066f">RuntimeException異常類包括運行時各類常見的異常,ArithmeticException類和ArrayIndexOutOfBoundsException類都是它的子類。所以,RuntimeException異常類的catch子句應該放在 最後面,不然可能會屏蔽其後的特定異常處理或引發編譯錯誤。</font>
try-catch語句還能夠包括第三部分,就是finally子句。它表示不管是否出現異常,都應當執行的內容。try-catch-finally語句的通常語法形式爲:
try { // 可能會發生異常的程序代碼 } catch (Type1 id1) { // 捕獲並處理try拋出的異常類型Type1 } catch (Type2 id2) { // 捕獲並處理try拋出的異常類型Type2 } finally { // 不管是否發生異常,都將執行的語句塊 }
例二, 帶finally子句的異常處理程序
public class TestException { public static void main(String args[]) { int i = 0; String greetings[] = { " Hello world !", " Hello World !! ", " HELLO WORLD !!!" }; while (i < 4) { try { // 特別注意循環控制變量i的設計,避免形成無限循環 System.out.println(greetings[i++]); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("數組下標越界異常"); } finally { System.out.println("--------------------------"); } } } }
運行結果:
try 塊:用於捕獲異常。其後可接零個或多個catch塊,若是沒有catch塊,則必須跟一個finally塊。
catch 塊:用於處理try捕獲到的異常。
finally 塊:不管是否捕獲或處理異常,finally塊裏的語句都會被執行。當在try塊或catch塊中遇到return語句時,finally語句塊將在方法返回以前被執行。在如下4種特殊狀況下,finally塊不會被執行:
1)在finally語句塊中發生了異常。
2)在前面的代碼中用了System.exit()退出程序。
3)程序所在的線程死亡。
4)關閉CPU。
雖然Java系統已經預約義好了不少異常類,可是有時會遇到預約義的異常類不能描述出現的錯誤。在這種狀況下,程序員能夠經過擴展Exception類及其子類來定義本身的異常類
格式以下
class 異常類名 extends Exception { public 異常類名(String msg) { super(msg); } }
throws 異常類名1,異常類名2
try{} catch(異常類名 y){} catch(異常類名 y){}
getMessage() //輸出異常的信息
printStackTrace() //輸出致使異常更爲詳細的信息
例子
CustomException.java
package me; class FormatException extends Exception { /** * */ private static final long serialVersionUID = 1L; private String ErrorMessage; public FormatException(String message) { super(message); ErrorMessage=message; } public String getMessage(){ return "該數組元素"+ErrorMessage+"不是偶數,不符合"; } } public class CustomException { int A[]={6,7,3,2,5,1}; public void g(int i)throws FormatException { System.out.println("一下輸出數組元素偶數"); for(i=0;i<=5;i++) { if(A[i]%2!=0) { throw new FormatException(String.valueOf(i)); } else System.out.println("A["+i+"]="+A[i]); } } public void run(int i){ try{ g(i); } catch(FormatException e) { e.getMessage();System.out.println(e); } finally{System.out.println("A["+i+"]="+A[i]); } } }
text.java
package me; public class Text { public static void main(String[] args) { CustomException a=new CustomException(); a.run(5); } }
運行結果:
歡迎關注個人微信公衆號:"Java面試通關手冊"(一個有溫度的微信公衆號,期待與你共同進步~~~堅持原創,分享美文,分享各類Java學習資源):