Java 複習筆記5 - 異常處理

異常處理

異常分類與體系結構:

image-20191121094447105

Error 相關類型的異常是程序沒法處理(大多都是修改代碼沒法解決的)的異常,這類異常一般須要咱們調整JVM的運行環境java

Exception 相關類型的異常是程序能夠處理的異常,其包含兩大子類型code

  • 編譯異常(CheckedException)對象

    一般是語法錯誤,或是方法明確指明可能拋出異常則必須捕獲處理blog

  • 運行時異常(RuntimeException)繼承

    指的是檢查階段沒有發現任何問題,知足全部語法規範,只有在運行時才能發現的異常編譯器

異常處理

關鍵字 try catch finally throws throw虛擬機

基本語法:it

image-20191121100239487

注意:io

  • try 沒法單獨使用,必須與catch 或finally 組合使用
  • finally 表示最終,即不管異常是否真的發生了,最終都會執行finally編譯

  • 當異常類型爲Exception時 表示通用異常處理(萬能異常處理),能夠捕獲全部異常可是沒法針對性的處理
  • 一個try能夠有多個catch
  • 一般將Exception添加到最後一個catch中做爲徹底保證,讓程序能夠繼續運行
  • 一個try中的全部catch下每一個異常類型只能出現一次
  • catch中異常類型必須從小到大(先子類在父類)
  • 不管有多個catch最終只有一個會被執行(相似 if else.....)
  • 如要打斷finally的執行能夠直接退出虛擬機,System.exit();

finally 對return的影響

在方法中,若是有finally,即便在 try 或catch中遇到了return 語句,方法也不會當即結束,而是必須執行完finally後纔會執行結束,

案例:

class Test{
  public static void main(String[] args){
        System.out.println(func(0));
    //此處獲得的結果爲10000;
    //若是沒有finally 則是10;
  }
  public static int func(int arg){
    try{
      int a = 1/arg;
      return a;
    }catch(Exception e){
      return 10;
    }finally{
      return 10000;
    }
  }
}
強調:方法中不管是否出現異常,返回值都以finally中的返回值爲準,這是不符合實際的,因此一般不這麼寫

拋出異常

throws

用於方法定義,在定義方法時可使用throws來聲明,方法可能會拋出某種類型的異常

image-20191121103939422

何時使用throws

當方法中可能會有異常,可是方法自己沒法處理,或是不想處理....就可使用throws來拋出

須要強調的是:若是一個異常拋出後沒最終沒有獲得處理,將致使程序運行中斷,因此一般咱們不能聽任無論

使用

image-20191121104306085

注意:

  • 簡單的說,只要聲明瞭,則代表方法內部不會處理該異常,誰調用就由誰處理;

  • 相應的調用者則須要捕獲異常並處理,若調用方也沒法處理,則能夠繼續向上拋出
  • 一個方法也能夠聲明拋出多種不一樣類型異常,響應的調用方應增長對應的catch

案例:

package com.yh.test;

public class Test {
    public static void main(String[] args){
       //一直拋向程序入口都沒有獲得處理則程序被終止
        func3();
    }
    static public void func2() throws ArithmeticException{
        int a = 1/0;
    }

    static public void func3() throws ArithmeticException{
        try{
            func2();//func2拋出異常
        }catch (Exception e){
           //沒法處理則繼續向上拋出
            throw e;
        }
    }
}

拋出多種類型異常:

import java.util.InputMismatchException;
import java.util.Scanner;

public class Test {
    public static void main(String[] args){
        try {
            func3();
        } catch (ArrayIndexOutOfBoundsException e) {
            e.printStackTrace();
        } catch (InputMismatchException e) {
            e.printStackTrace();
        }
    }
    static public int func3() throws ArrayIndexOutOfBoundsException,InputMismatchException{//        try{
            int a = new Scanner(System.in).nextInt();
            return 10/a;
    }
}

throw

主動拋出異常

image-20191121110702483

使用場景:

當方法的提供者須要調用者提供一些數據,可是這些數據不合法,致使功能沒法正常處理時,就應該主動拋出異常

調用方能夠在捕獲到異常後進行處理

拋出仍是處理?

方法內部致使的異常本身處理,調用者致使的異常則拋出(或者能處理則處理)

疑惑:爲何throws Exception時編譯器要求必須提供解決方案?

由於Exception 既包含了運行時異常 又包含了 編譯時異常,因此要求必須處理,由此可知,當throws聲明的異常爲編譯時異常時則要求必須提供處理代碼;

案例:

package com.yh.test;

public class Test {
    public static void main(String[] args){
        try {
            func(1);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static void func(int a) throws  Exception{
        if (a < 1){
            throw new Exception("參數不能小於1");
        }
    }
}

自定義異常

當內置異常沒法知足特色業務場景時,能夠自定義異常類,只須要繼承Exception便可

案例:

class MyException extends Exception{
    public MyException() {
        super("固定的異常提示!");
    }
}

當異常提示信息固定的時候能夠像上面同樣定義構造器

異常鏈

當一個方法拋出的異常被調用方法捕獲,可是調用方法又拋出了新的異常時,則造成了異常鏈,

若是咱們在調用方法中直接拋出新的異常不作任何額外的操做時,原始異常信息則被丟失;

咱們有兩個方法能夠保留原始異常信息

1.實例化時使用原始異常做爲參數

2.實例化後調用initCause傳入原始異常對象

案例:

package com.yh.test;

public class ExceptionLinkeTest {
    public static void main(String[] args) {
        try {
            func2();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    static public void fun1() throws ArithmeticException{
        int a = 1 / 0;
    }

    static public void func2() throws Exception{
        try{
            fun1();
        }catch (ArithmeticException e){
            //不保留原始異常信息
            //throw  new Exception("新的異常信息!");
          
            //保留異常信息方法1
            throw  new Exception("新的異常信息!",e);
          
            //保留異常信息方法2
              Exception newex = new Exception("新的異常信息!");
            newex.initCause(e);
            throw newex;          
        }
    }
}

當咱們不作處理時,獲得的異常信息以下:

image-20191121115914351

使用 方法1或方法2 來保留異常信息結果以下:

image-20191121120017971

相關文章
相關標籤/搜索