Error與Exception的區別和詳解
Error類和Exception類都繼承自Throwable類。
Error類和Exception類的繼承關係:
區別:
Exception:
1.可以是可被控制(checked) 或不可控制的(unchecked)。
2.表示一個由程序員導致的錯誤。
3.應該在應用程序級被處理。
Error:
1.總是不可控制的(unchecked)。
2.經常用來用於表示系統錯誤或低層資源的錯誤。
3.如何可能的話,應該在系統級被捕捉。
java.lang.Error:
Throwable的子類,用於標記嚴重錯誤。合理的應用程序不應該去try/catch這種錯誤。絕大多數的錯誤都是非正常的,就根本不該出現的。
java.lang.Exception:
Throwable的子類,用於指示一種合理的程序想去catch的條件。即它僅僅是一種程序運行條件,而非嚴重錯誤,並且鼓勵用戶程序去catch它。
Java 中定義了兩類異常:
- Checked exception:
這類異常都是Exception的子類 。異常的向上拋出機制進行處理,假如子類可能產生A異常,那麼在父類中也必須throws A異常。可能導致的問題:代碼效率低,耦合度過高。 - Unchecked exception:
這類異常都是RuntimeException的子類,雖然RuntimeException同樣也是Exception的子類,但是它們是非凡的,它們不能通過client code來試圖解決,所以稱爲Unchecked exception 。
Java 中異常類的繼承關係圖:
常見的幾種RuntimeException如下:
NullPointerException - 空指針引用異常
ClassCastException - 類型強制轉換異常。
IndexOutOfBoundsException - 下標越界異常
NumberFormatException - 數字格式異常
比較常見的異常題目
- try{} 裏有一個 return 語句,那麼緊跟在這個 try 後的 finally{} 裏的 code
會不會被執行,什麼時候被執行,在 return 前還是後?
答案:會執行,在方法返回調用者前執行。
- Java語言如何進行異常處理,關鍵字:throws、throw、try、catch、finally分別如何使用?
答: Java通過面向對象的方法進行異常處理,把各種不同的異常進行分類,並提供了良好的接口。在Java中,每個異常都是一個對象,它是Throwable類或其子類的實例。當一個方法出現異常後便拋出一個異常對象,該對象中包含有異常信息,調用這個對象的方法可以捕獲到這個異常並可以對其進行處理。
Java的異常處理是通過5個關鍵詞來實現的:try、catch、throw、throws和finally。
一般情況下是用try來執行一段程序,如果系統會拋出(throw)一個異常對象,可以通過它的類型來捕獲(catch)它,或通過總是執行代碼塊(finally)來處理;try用來指定一塊預防所有異常的程序;catch子句緊跟在try塊後面,用來指定你想要捕獲的異常的類型;throw語句用來明確地拋出一個異常;throws用來聲明一個方法可能拋出的各種異常(當然聲明異常時允許無病呻吟);finally爲確保一段代碼不管發生什麼異常狀況都要被執行;try語句可以嵌套,每當遇到一個try語句,異常的結構就會被放入異常棧中,直到所有的try語句都完成。如果下一級的try語句沒有對某種異常進行處理,異常棧就會執行出棧操作,直到遇到有處理這種異常的try語句或者最終將異常拋給JVM。
- 運行時異常與受檢異常有何異同?
答:異常表示程序運行過程中可能出現的非正常狀態,
運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤,只要程序設計得沒有問題通常就不會發生。
受檢異常跟程序運行的上下文環境有關,即使程序設計無誤,仍然可能因使用的問題而引發。
Java編譯器要求方法必須聲明拋出可能發生的受檢異常,但是並不要求必須聲明拋出未被捕獲的運行時異常。
源碼
下面是我自己寫的自定義異常,自定義異常類(繼承運行時異常),歡迎大家指教
MyException類
package com.demo.Exception;
/**
* 自定義異常類(繼承運行時異常)
* @author liu.hb
* @version 2018/11/19
*/
public class MyException extends RuntimeException{
private static final long serialVersionUID = 1L;
/**
* 錯誤編碼
*/
private String errorCode;
/**
* 消息是否爲屬性文件中的Key
*/
private boolean propertiesKey = true;
/**
* 構造一個基本異常.
*
* @param message
* 信息描述
*/
public MyException(String message)
{
super(message);
}
/**
* 構造一個基本異常.
*
* @param errorCode
* 錯誤編碼
* @param message
* 信息描述
*/
public MyException(String errorCode, String message)
{
this(errorCode, message, true);
}
/**
* 構造一個基本異常.
*
* @param errorCode
* 錯誤編碼
* @param message
* 信息描述
*/
public MyException(String errorCode, String message, Throwable cause)
{
this(errorCode, message, cause, true);
}
/**
* 構造一個基本異常.
*
* @param errorCode
* 錯誤編碼
* @param message
* 信息描述
* @param propertiesKey
* 消息是否爲屬性文件中的Key
*/
public MyException(String errorCode, String message, boolean propertiesKey)
{
super(message);
this.setErrorCode(errorCode);
this.setPropertiesKey(propertiesKey);
}
/**
* 構造一個基本異常.
*
* @param errorCode
* 錯誤編碼
* @param message
* 信息描述
*/
public MyException(String errorCode, String message, Throwable cause, boolean propertiesKey)
{
super(message, cause);
this.setErrorCode(errorCode);
this.setPropertiesKey(propertiesKey);
}
/**
* 構造一個基本異常.
*
* @param message
* 信息描述
* @param cause
* 根異常類(可以存入任何異常)
*/
public MyException(String message, Throwable cause)
{
super(message, cause);
}
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public boolean isPropertiesKey() {
return propertiesKey;
}
public void setPropertiesKey(boolean propertiesKey) {
this.propertiesKey = propertiesKey;
}
}
測試類 MyExceptionTest
package com.demo.Exception;
public class MyExceptionTest {
public static void main(String[] args) {
String[] sexs = {"男性","女性","中性"};
for(int i = 0; i < sexs.length; i++){
if("中性".equals(sexs[i])){
throw new MyException("你全家都是中性!");
}else{
System.out.println(sexs[i]);
}
}
}
}