美團迴應《維護外賣送餐員權益指導意見》:已展開多輪調研,將堅決貫徹落實
阿新 • • 發佈:2021-07-26
異常
概念:程式中出現的不正常現象就是異常
繼承體系
異常中的頂級父類:
Java.lang.Throwable : 所有有異常和錯誤的父類
|--Java.lang.Error : 所有錯誤的父類
|--Java.lang.Exception : 所有異常的父類
|--Java.lang.RuntimeExceptiion : 所有執行時異常的父類
頂級父類Throwable的方法
String toString() //返回詳細異常資訊 String getMessage() //返回簡單異常資訊 void printStackTrace() //異常資訊追蹤到標準的錯誤流,最詳細,綜合了以上兩個另外還有異常發生的程式碼行
以上方法為頂級父類的方法,其子類可直接使用。
預設的異常處理情況
預設情況即無人工干預的情況,JVM的處理方式
- 方法中異常發生,處理不了,向上丟擲給呼叫者,呼叫者也處理不了,拋給jvm
jvm看你們都不處理,那我直接輸出資訊,結束程式。之後的程式碼不在執行!
- 沒有異常,繼續執行程式
try...catch異常處理
try catch的異常處理的格式寫法 :
try{ 被檢測的程式碼 可能發生異常的程式碼 }catch(異常類的類名 變數名){ 異常的處理方式 : 寫什麼都可以 定義變數,建立物件,呼叫方法,迴圈,判斷... 只要寫了catch,異常就被處理掉了 }
public static void main(String[] args) { int[] arr = {1}; //try catch異常處理 try { int i = getNum(arr); System.out.println("i = " + i); }catch (Exception ex){ //括號中寫異常型別,不知道些什麼直接寫異常頂級父類,(多型) System.out.println("異常被處理掉"); } System.out.println(111); } public static int getNum(int[] arr){ return arr[1] + 10; }
多catch並行處理
異常處理的程式碼中 : try 可以跟隨多個catch
好處:針對方法中出現不同的異常可以分開處理
public static void main(String[] args) {
/**
* myExec出現2個異常
* 寫2個catch分別捕獲異常
*/
try {
myExec(0);
}catch (NullPointerException ex){
System.out.println("處理空指標異常");
}catch (ArrayIndexOutOfBoundsException ex){
System.out.println("處理越界異常");
}
}
/**
* 定義方法,目的引發異常
* 傳遞引數 : 對引數進行判斷 會出現不同的異常
*/
public static void myExec(int i){
if ( i == 0){
//引發空指標異常
String s = null;
int len = s.length();
}else {
//引發越界異常
int[] arr = {};
int a = arr[0];
}
}
多個catch處理異常的時候,寫法特別注意 : 如果catch中的異常類沒有關係,先寫後寫沒有區別, catch中的異常類有繼承關係,父類寫在最下面
throw和throws 關鍵字的使用
- throw只能寫在方法的內部,後面跟隨物件的建立
- throws只能寫在方法的定義上即方法的後面,後面跟隨異常類名
public static void main(String[] args) {
/**
* getArea()呼叫方法,方法上有異常
* 只能處理,不處理編譯失敗
* 在main的方法上加throws 異常沒有處理,交給JVM處理
* try catch處理
*/
try {
int area = getArea(-10);
System.out.println(area);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 功能: 計算正方形的面積
* 需要引數 : 邊長
* 語法 : 方法的內部出現了異常,必須在方法定義上暴露
*/
public static int getArea(int length) throws Exception{
if (length <= 0)
//資料錯誤,導致後面的計算不能進行
//內部出現問題
throw new Exception("邊長不存在");
return length * length;
}
finally程式碼塊
-
finally程式碼塊跟隨try ... catch使用,也有跟隨try使用
-
finally語句一定會執行,除非結束jvm
-
主要用於釋放資源(資料庫連線等)
public static void main(String[] args) { try { int[] arr = {1}; System.out.println(arr[0]); }catch (Exception ex){ ex.printStackTrace(); }finally { //後期用於資源的釋放 System.out.println("這裡的程式碼,必須執行"); } }
兩個噁心的題目
public class ExceptionText {
public static void main(String[] args) {
System.out.println(finallyTest1());//輸出3
System.out.println(finallyTest2());//輸出1
}
//題1:
public static int finallyTest1() {
try {
return 1; //沒有異常,catch裡肯定不會執行,準備返回1,但finally的3將其覆蓋
}catch (Exception ex){
return 2;
}finally {
return 3;
}
}
//題2:
public static int finallyTest2() {
int a = 1;
try {
return a; //此處a已經變為1,即return 1,即將返回;
// finally執行後a=2;不關我return 1的事
}catch (Exception ex){
return a;
}finally {
++a;
}
}
}
RuntimeException異常
Exception
|--RuntimeExceptiion
|-- NullPointerException
|-- ...
RuntimeException和他的所有子類,都稱為執行異常,非子類的稱為編譯異常
- 編譯異常 : 方法出現編譯異常,呼叫者必須處理,否則編譯失敗.處理方式可以是try catch或者是throws都可以,程式內部拋給你的。
- 執行異常 : 方法出現執行異常,方法的定義上,不需要throws宣告,呼叫者也不需要處理這個異常,直接修改程式碼
不要處理執行異常 : 程式一旦發生執行異常,請程式人員修改原始碼
- 常見的執行異常
NullPointerException
空指標IndexOutOfBoundsException
越界異常ClassCastException
型別強制 (型別轉換異常)IllegalArgumentException
非法的引數異常
自定義異常
Java官方已經定義了大量的異常類,但是依然不夠,在做專案的時候,Jdk中沒有與我們需要相匹配的異常類,故需要我們自己寫。
- 自定義前提繼承Exception或者RuntimeException,(只有Exception和他的子類,才具有可丟擲性)
- 自定義的類中,構造方法,super呼叫父類構造方法,傳遞異常資訊
/**
* 自定義的異常類
* 成績負數的異常
* 繼承哪個父類呢
*
* 自定義異常資訊 : 繼承父類 RuntimeException 帶有String型別的構造方法 (String 異常資訊)
*/
public class ScoreException extends RuntimeException{
public ScoreException(String s){
super(s);
}
}
public static void main(String[] args) {
// int[] arr = {1};
//System.out.println(arr[2]);
int avg = getAvg(-100,2);
System.out.println("avg = " + avg);
}
/**
* 計算成績的平均分
*/
public static int getAvg(int math,int chinese){
//判斷成績的數值
if ( math < 0 || chinese < 0)
//手動丟擲,自己定義的異常
throw new ScoreException("成績不存在");
return (math + chinese) / 2;
}