異常 學習異常的筆記記錄 異常 異常的概念 指的是程式在執行過程中,出現的非正常的情況,最終會導致JVM的非正常停止。 異常指的並不是語法錯誤,語法錯了,編譯不通過,不會產生位元組碼文件,根本不能運行. 異常的體系 簡單劃分下 : Throwable : java語言中所有異常和錯誤的超類 | Exc ...
異常
學習異常的筆記記錄
異常
異常的概念
指的是程式在執行過程中,出現的非正常的情況,最終會導致JVM的非正常停止。
異常指的並不是語法錯誤,語法錯了,編譯不通過,不會產生位元組碼文件,根本不能運行.
異常的體系
簡單劃分下 :
Throwable : java語言中所有異常和錯誤的超類
|-- Exception : 編譯期異常(日期格式化,日期解析,需要try-catch/throws拋出)
|--RuntimeException : 運行期異常(數組越界異常)
|--Error : 錯誤(數組創建長度過大)
異常(Exception)的分類
- 編譯期異常 :在編譯時期就要處理(IO流的文件不存在,日期解析格式化),不處理便已不能通過
- 運行期異常 : 在運行時出現的異常(/by zero,索引越界等等)
舉個例子(異常是怎麼產生的和產生後如何處理) :
異常的處理
throw 關鍵字:
- 作用 : 可以使用throw關鍵字在指定的方法中拋出異常
使用格式 : throw new xxxException("異常產生的原因"");
1.throw new 必須寫在方法的內部
2.throw new 後面的對象必須是Exception類或者是Exception的子類對象
3.throw拋出RuntimeException或者它的子類,可以不處理,交給JVM處理.
拋出編譯異常,就必須處理該異常,try{}catch{}或者throws
throws 關鍵字:
- 作用 : 當方法內部拋出異常對象的時候,處理時可以使用throws拋出給調用者,讓調用者處理.
使用格式 : 在方法聲明時在最後使用throws拋出
修飾符 返回值類型 方法名(參數列表) throws xxxException{}
1.throws關鍵字必須寫在方法聲明處
2.throws關鍵字後邊聲明的異常必須是Exception或者是他的子類
3.方法內部如果拋出多個異常,throws也必須寫多個異常,存在父子關係的,可以直接寫父類,如果都寫子類必須在父類的前面
4.調用方法處理時,可以繼續使用throws,也可以try{}catch{}
throw與throws的區別 :
- 位置不同,前者方法中,後者方法聲明處
- 含義不同,前者製造異常,後者是處理異常
- 格式不同,throw + 異常對象,throws + 異常名稱(多個異常,使用逗號隔開就好)
try..catch..:
格式 :
try{ 可能出現問題的代碼 }catch(異常類型 變數名){ // 聲明異常變數 處理異常的代碼 // 儘量不要只用printStackTrace() 處理 }
執行流程 : try內代碼出現異常,catch會捕獲異常(使用catch中的類型進行匹配,匹配成功之後就會執行catch內的代碼
如果匹配失敗,則繼續向上拋出,交給調用者去處理,最後都沒有處理時會交給JVM進行處理),try出現異常的地方後面的代碼
停止執行,執行catch內的代碼,如果try內沒有出現異常代碼正確執行,不會執行catch的代碼.
try...catch..finally :
- 當程式出現一種需求,無論程式是否出現異常,都需要執行某個代碼塊(比如流的關閉,sql連接關閉等等),這個時候就需要finally了
格式 :
try{ 可能出現異常的代碼 } catch(異常類型 變數名){ 異常處理 } finally{ 無論是否出現異常都需要執行的代碼 }
執行流程 : 在try..catch的基礎上,catch執行完畢或者JVM處理完異常之後,執行finally代碼塊,除非使用System.exit(0)強行停止代碼.
不要再finally中使用return語句,雖然語法上無錯誤,但儘量避免,finally語句一般用於回收資源,
如果在try或catch中進行一個返回值.這個時候這個返回通道的值已經確定,在finally語句中修改值,這個
時候返回值並不會被修改.
舉個例子,用來說明上面那個返回通道的問題:
Throwable類定義了處理異常的三個方法:
- public String getMessage() :獲取異常的描述信息,原因(提示給用戶的時候,就提示錯誤原因。
- public String toString() :獲取異常的類型和異常描述信息(不用)。
- public void printStackTrace() :列印異常的跟蹤棧信息並輸出到控制台。
多個異常如何處理:
- 多次捕獲,多次處理(也就是每個可能出現異常的代碼都使用一個try..catch進行捕獲處理)
- 一次捕獲,多次處理(也就是一個try,多個catch,註意的是catch中有子父類關係,子類異常必須在父類異常的前面)
- 一次捕獲,一次處理(也就是catch中使用具有較高父類的Exception對象)(建議使用)
舉個例子:
public class TryCatchDemo {
public static void main(String[] args) {
// 多個異常多個處理
try {
// 產生空指針異常(創建對象賦值為null,使用對象調用方法可以產生空指針異常)
Integer integer = null;
System.out.println(integer.toString());
} catch (NullPointerException e) {
e.printStackTrace();
}
// 出現的順序很奇怪,正好體現的是多線程
try {
// 產生字元串越界異常,訪問字元串的索引查過字元串的長度就可以產生
String s = "dilireba";
for(int i = 0; i <= s.length(); i++){
System.out.println(s.charAt(i));
}
} catch (StringIndexOutOfBoundsException e) {
e.printStackTrace();
}
// 多個異常一次捕獲,多次處理
try {
// 產生空指針異常(創建對象賦值為null,使用對象調用方法可以產生空指針異常)
Integer integer = null;
System.out.println(integer.toString());
// 產生字元串越界異常,訪問字元串的索引查過字元串的長度就可以產生
String s = "dilireba";
for(int i = 0; i <= s.length(); i++){
System.out.println(s.charAt(i));
}
// 會出現NullPointerException,因為第一次異常之後後面的代碼停止執行
} catch (NullPointerException e) {
e.printStackTrace();
}catch (StringIndexOutOfBoundsException e) {
e.printStackTrace();
}
// 多個異常一次捕獲,一次處理,建議使用這種
try {
// 產生空指針異常(創建對象賦值為null,使用對象調用方法可以產生空指針異常)
Integer integer = null;
System.out.println(integer.toString());
// 產生字元串越界異常,訪問字元串的索引查過字元串的長度就可以產生
String s = "dilireba";
for(int i = 0; i <= s.length(); i++){
System.out.println(s.charAt(i));
}
} catch (Exception e) { // 實際上是使用了多態
// 會出現NullPointerException,因為第一次異常之後後面的代碼停止執行
e.printStackTrace();
}
}
}
異常的註意事項:
1.如果父類拋出了多個異常,子類覆蓋父類方法時,只能拋出相同的異常或者是他的子集。
2.父類方法沒有拋出異常,子類覆蓋父類該方法時也不可拋出異常。此時子類產生該異常,只能捕獲處理,不
能聲明拋出
3.運行時異常被拋出可以不處理。即不捕獲也不聲明拋出。
4.在try/catch後可以追加finally代碼塊,其中的代碼一定會被執行,通常用於資源回收。
5.如果finally有return語句,永遠返回finally中的結果,避免該情況.
自定義異常
Java提供的異常類,有時候對於我們來說不夠用,做不到見名知意,這個時候需要自定義異常類
格式 :
public class XXXException extends Exception | RuntimeException{ 添加一個空參數構造方法 添加一個帶異常信息的構造方法 }
註意 :
1.自定義異常一般都是以Exception結尾的,說明該類是一個異常類
2.自定義異常類,必須繼承Exception或者是RuntimeException,前者用於自定義編譯期異常,後者用於自定義運行期異常(可以不處理,交給JVM處理).如下所示,自定義異常類:
/** * 自定義異常類,在進行開發的時候一定要做到見名知意 * * @author WZLOVE * @create 2018-07-16 15:53 */ public class MyException extends Exception{ // 自定義編譯期異常類,繼承Exception類,重寫兩個構造方法 public MyException() { } public MyException(String message) { super(message); } }
可以嘗試著自己寫一個註冊的異常類,嘗試一下.