Java入門系列-20-異常

爲何要進行異常處理

下面這段代碼可否正常執行java

public class DemoCalc {
    public static void main(String[] args) {
        int a=0;
        int b=0;
        int c=a/b;
        System.out.println("運算結果爲:"+c);
    }
}

結果是咱們在控制檯中看到一段錯誤提示,那是由於除數不能爲0。異常就是在程序運行過程當中發生的不正常事件,會中斷運行的程序程序員

Java 使用了異常處理機制爲程序提供了錯誤處理的能力,在程序中預先設置好對付異常的處理辦法,待程序發生異常時對異常進行處理,處理完畢後,程序即可以繼續運行。數組

下面來看一下Java中是如何進行異常處理的調試

如何進行異常處理

Java 的異常處理是經過5個關鍵字實現的:try、catch、finally、throw、throwscode

關鍵字 做用
try 執行可能產生異常的代碼
catch 捕獲異常
finally 不管是否發生異常,代碼總能執行
throws 聲明方法要拋出的異常
throw 手動拋出異常

常見異常及異常分類

Throwable 是Java 中全部錯誤和異常的父類orm

Error類:Throwable的子類,僅靠程序自己沒法恢復的嚴重的錯誤。對象

Exception類:Throwable的子類,由Java應用程序拋出和處理的非嚴重錯誤事件

RuntimeException類:Exception的子類,運行時異常,不要求程序必須作出處理。get

Checked異常:Exception的子類,程序必須處理該類異常。input

常見異常類型

異常類型 說明
Exception 異常層次結構的父類
ArithmeticException 算數錯誤情形,如以零做除數
ArrayIndexOutOfBoundsException 數組下標越界
NullPointerException 嘗試訪問null對象成員
ClassNotFoundException 不能加載所需的類
IllegalArgumentException 方法接收到非法參數
ClassCastException 對象強制類型轉換出錯
NumberFormatException 數字格式轉換異常,如把"abc"轉換成數字

try-catch

語法:

public void method(){
    try{
        //代碼段1
        //可能產生異常的代碼段
        //代碼段2
    }catch(異常類型 ex){
        //對異常進行處理的代碼段
    }
    //代碼段
}

try-catch塊捕獲異常有三種狀況:

一、try塊中沒有任何異常,try中正常,catch不會執行,正常執行try-catch後的代碼。

二、try塊中可能發生異常的代碼段發生異常,代碼段2不會執行,而是執行catch中異常處理的代碼,正常執行try-catch後的代碼。

catch中異常類型的printStackTrace() 方法能進行堆棧跟蹤顯示出程序運行到當前類的執行流程,異常堆棧信息中包含了異常的類型及異常出現的位置。

三、異常類型不匹配,程序將中斷。好比try產生的異常爲ArithmeticException,catch卻用了 ClassCastException。

在控制檯中接收數字作除法運算

import java.util.Scanner;

public class DemoInput {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        try{
            System.out.println("請輸入被除數(整數):");
            int a=input.nextInt();
            System.out.println("請輸入除數(整數):");
            int b=input.nextInt();
            int c=a/b;
            System.out.println("結果:"+c);
        }catch(Exception ex) {
            ex.printStackTrace();
        }
        System.out.println("程序結束");
    }
}

try-catch-finally

語法:

public void method(){
    try{
        //可能會發生異常的代碼
    }catch(異常類型 ex){
        //異常處理
    }finally{
        //不管如何都要執行的代碼
    }
}

finally塊:是否發生異常都執行

finllay塊不執行的惟一狀況:以前的代碼中執行了 System.exit(1); 退出虛擬機

try-catch-finally的使用

import java.io.FileNotFoundException;
import java.util.Scanner;

public class DemoInput {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        try{
            System.out.println("請輸入被除數(整數):");
            int a=input.nextInt();
            System.out.println("請輸入除數(整數):");
            int b=input.nextInt();
            int c=a/b;
            System.out.println("結果:"+c);
        }catch(Exception ex) {
            ex.printStackTrace();
        }finally {
            System.out.println("感謝您的使用");
        }
        System.out.println("程序結束");
    }
}

若是在try塊或catch塊中有return語句,finally是否還會執行?運行下面代碼斷點調試觀察結果。

public class TestReturn {

    public static void main(String[] args) {
        try {
            int a=1+1;
            System.out.println("try執行");
            return;
        } catch (Exception e) {
            System.out.println("catch執行");
        }finally {
            System.out.println("finally執行");
        }
    }
}

try塊或catch塊中能夠有return語句,若是有return語句會先執行finally最後再執行return。

多重catch

try塊中可能會發生多種異常,若是要不一樣的異常進行不一樣的處理,須要使用多重catch進行處理。

語法:

public void method(){
    try{
        //可能發生異常的代碼段
    }catch(異常類型1 e){
        //對異常類型1進行的處理的代碼段
    }catch(異常類型2 e){
        //對異常類型2進行的處理的代碼段
    }catch(異常類型n e){
        //對異常類型n進行的處理的代碼段
    }
}

當try塊中發生異常後,會逐個與catch中的異常類型進行匹配,匹配成功後,進入對應的catch進行異常處理,處理完成後再也不進入其餘catch,程序繼續執行。

排列catch語句的順序是:先子類後父類

發生異常時按順序逐個匹配

只執行第一個與異常類型匹配的catch語句

將以前的代碼 DemoInput.java 改形成多重catch

import java.io.FileNotFoundException;
import java.util.InputMismatchException;
import java.util.Scanner;

public class DemoInput {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        try{
            System.out.println("請輸入被除數(整數):");
            int a=input.nextInt();
            System.out.println("請輸入除數(整數):");
            int b=input.nextInt();
            int c=a/b;
            System.out.println("結果:"+c);
        }catch(InputMismatchException e) {
            System.out.println("輸入的數有誤!");
        }catch(ArithmeticException e) {
            System.out.println("除數不能爲0");
        }catch(Exception ex) {
            System.out.println("發生未知異常");
        }finally {
            System.out.println("感謝您的使用");
        }
        System.out.println("程序結束");
    }
}

聲明異常 throws

若是一個方法體內拋出了異常如何通知調用者,能夠在方法上聲明異常。

public class TestThrows {
    
    //聲明異常,多個異常能夠用逗號隔開
    public void test()throws Exception,ClassNotFoundException{
        //可能會發生異常的代碼
    }
}

處理方式一:調用者處理異常

public static void main(String[] args) {
    TestThrows t=new TestThrows();
    try {
        t.test();
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

處理方式二:調用者繼續聲明異常

public static void main(String[] args) throws ClassNotFoundException, Exception {
    TestThrows t=new TestThrows();
    t.test();
}

main方法繼續聲明異常,調用者就變成虛擬機了,發生異常則按默認方式處理,打印出來。

拋出異常 throw

除了系統自動拋出的異常外,有些問題須要程序員自行拋出異常

public class TestThrow {
    public void inputAge(int age) throws Exception {
        if (age<1) {
            throw new Exception("還有這種年齡?");
        }
    }
    
    public static void main(String[] args) {
        TestThrow t=new TestThrow();
        try {
            t.inputAge(-1);
        } catch (Exception e) {
            System.out.println("年齡有誤:"+e.getMessage());
        }
    }
}

自行拋出異常後,還須要在方法上聲明異常

相關文章
相關標籤/搜索