JAVA基礎再回首(十九)——異常的概述、Try…Catch、多異常處理、Throws、throw、finally、自定義異常及異常的注意事項

JAVA基礎再回首(十九)——異常的概述、Try…Catch、多異常處理、Throws、throw、finally、自定義異常及異常的注意事項

版權聲明:轉載必須註明本文轉自程序員杜鵬程的博客:http://blog.csdn.net/m366917


前面我們學習了集合,現在我們開始IO流的學習
學習io流之前呢,我們先來學習異常

異常的概述

  • 異常概述
    • 異常就是Java程序在運行過程中出現的錯誤。
  • 由來
    • 問題也是現實生活中一個具體事務,也可以通過java 的類的形式進行描述,並封裝成對象。
    • 其實就是Java對不正常情況進行描述後的對象體現。

異常的分類圖解

這裏寫圖片描述

從上面的圖我們可以看到:程序的異常Throwable分爲兩類

  • 程序的異常:Throwable
    • 嚴重問題:Error 我們不處理。這種問題一般都是很嚴重的,比如說內存溢出。
    • 問題:Exception
      • 編譯期問題:不是RuntimeException的異常 必須進行處理的,因爲你不處理,編譯就不能通過。
      • 運行期問題:RuntimeException 這種問題我們也不處理,因爲是你的問題,而且這個問題出現肯定是我們的代碼不夠嚴謹,需要修正代碼的。

如何程序出現了問題,我們沒有做任何處理,最終jvm會做出默認的處理。
把異常的名稱,原因及出現的問題等信息輸出在控制檯。

public class ExceptionDemo {
    public static void main(String[] args) {

        int a = 10;
        int b = 0;
        System.out.println(a / b);

        System.out.println("over");
    }
}

這裏寫圖片描述
我們運行程序,可以看到異常出現了。它爲什麼會出現異常呢?


  • JVM的默認處理方案
    • 把異常的名稱,錯誤原因及異常出現的位置等信息輸出在了控制檯
    • 程序停止執行

我們在來理解一下JVM的默認處理方案

jvm發現運算是已經違反了數學運算規則,java將這種常見的問題進行描述,並封裝成了對象叫做ArithmeticException
當除0運算髮生後,jvm將該問題打包成了一個異常對象.
並將對象拋給調用者main函數,new ArithmeticException(“/by zero”);

main函數收到這個問題時,有兩種處理方式:
1. 自己將該問題處理,然後繼續運行
2.自己沒有針對的處理方式,只有交給調用main的jvm來處理

jvm有一個默認的異常處理機制,就將該異常進行處理.並將該異常的名稱,異常的信息.異常出現的位置打印在了控制檯上
同時將程序停止運行

Try…Catch

那麼我們自己如何處理異常呢?

  • 異常的處理方案
    • try…catch…finally
    • throws
 try...catch...finally的處理格式:
        try {
            可能出現問題的代碼;
        }catch(異常名 變量) {
            針對問題的處理;
        }finally {
            釋放資源;
        }
  變形格式:
        try {
            可能出現問題的代碼;
        }catch(異常名 變量) {
            針對問題的處理;
        }

注意:
try裏面的代碼越少越好
catch裏面必須有內容,哪怕是給出一個簡單的提示

那麼我們就來處理一下上面的異常吧

public class ExceptionDemo {
    public static void main(String[] args) {

        int a = 10;
        int b = 0;

        try {
            System.out.println(a / b);
        } catch (ArithmeticException ae) {
            System.out.println("除數不能爲0");
        }

        System.out.println("over");
    }
}

我們運行程序看控制檯
這裏寫圖片描述

多異常處理

上面我們處理了一個簡單的異常,如果我們遇到一個複雜的程序需要我們處理多個異常要怎麼辦呢?下面我們來學習

  • 多異常的處理

    • 每一個寫一個try…catch(這樣有點過於麻煩)
    • 寫一個try,多個catch
            try{
                ...
            }catch(異常類名 變量名) {
                ...
            }
            catch(異常類名 變量名) {
                ...
            }
            ...
            //注意事項:
                1:能明確的儘量明確,不要用大的來處理。
                2:平級關係的異常誰前誰後無所謂,如果出現了子父關係,父必須在後面。
public class ExceptionDemo {
    public static void main(String[] args) {
         method();
         System.out.println("----------");
        methods();
    }

    // 兩個異常的處理
    public static void method() {
        int a = 10;
        int b = 0;
        int[] arr = { 1, 2, 3 };

        try {
            System.out.println(arr[3]);
            System.out.println(a / b);
        } catch (ArithmeticException e) {
            System.out.println("除數不能爲0");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("你訪問了不該的訪問的索引");
        }

        System.out.println("over");
    }
    //多個異常的處理
    public static void methods() {
        int a = 10;
        int b = 0;
        int[] arr = { 1, 2, 3 };

        try {
            System.out.println(a / b);
            System.out.println(arr[3]);
            System.out.println("這裏出現了一個異常");
        } catch (ArithmeticException e) {
            System.out.println("除數不能爲0");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("你訪問了不該的訪問的索引");
        } catch (Exception e) {
            System.out.println("出問題了");
        }

        System.out.println("over");
    }
}

我們運行程序看結果
這裏寫圖片描述

我們看結果可以總結以下經驗
一旦try裏面出了問題,就會在這裏把問題給拋出去,然後和catch裏面的問題進行匹配,一旦有匹配的,就執行catch裏面的處理,然後結束了try…catch繼續執行後面的語句。

Throwable中的方法

  • getMessage():獲取異常信息,返回字符串。
  • toString():獲取異常類名和異常信息,返回字符串。
  • printStackTrace():獲取異常類名和異常信息,以及異常出現在程序中的位置。返回值void。
  • printStackTrace(PrintStream s):通常用該方法將異常內容保存在日誌文件中,以便查閱。

異常聲明Throws

有些時候,我們是可以對異常進行處理的,但是又有些時候,我們根本就沒有權限去處理某個異常。或者說,我處理不了,我就不處理了。
爲了解決出錯問題,Java針對這種情況,就提供了另一種處理方案:拋出。

  • 格式:
    • throws 異常類名
    • 注意:這個格式必須跟在方法的括號後面。
public class ExceptionDemo {
    public static void main(String[] args) {
        System.out.println("今天天氣很好");
        try {
            method();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println("但是我要在家學習");

        method2();
    }

    // 編譯期異常的拋出,編譯不通過,我們就要拋出異常了
    public static void method() throws ParseException  {
        String s = "2016-09-03";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date d = sdf.parse(s);
        System.out.println(d);
    }

    // 運行期異常的拋出
    public static void method2() throws ArithmeticException {
        int a = 10;
        int b = 0;
        System.out.println(a / b);
    }

}

運行結果
這裏寫圖片描述

在編譯期異常會提示給我們讓我們進行處理
這裏寫圖片描述
如果我們只是拋出了異常,那麼我們調用方法時,還是要處理這個異常的,看下圖
這裏寫圖片描述

所以呢,我們就得出一下結論:

  • 編譯期異常拋出,將來調用者必須處理。
  • 運行期異常拋出,將來調用可以不用處理。

throw

上面講了throws,那麼throw又是什麼鬼,怎麼用,他們有什麼區別呢,讓我們帶着疑問出發

先了解他的概念:
throw:在功能方法內部出現某種情況,程序不能繼續運行,需要進行跳轉時,就用throw把異常對象拋出。如果出現了異常情況,我們可以把該異常拋出,這個時候的拋出的應該是異常的對象。

throws和throw的區別

  • throws

    • 用在方法聲明後面,跟的是異常類名
    • 可以跟多個異常類名,用逗號隔開
    • 表示拋出異常,由該方法的調用者來處理
    • throws表示出現異常的一種可能性,並不一定會發生這些異常
  • throw

    • 用在方法體內,跟的是異常對象名
    • 只能拋出一個異常對象名
    • 表示拋出異常,由方法體內的語句處理
    • throw則是拋出了異常,執行throw則一定拋出了某種異常

學了這麼多異常的處理,那麼我們到底該如何處理異常呢?我們來總結一下

  • 原則:如果該功能內部可以將問題處理,用try,如果處理不了,交由調用者處理,這是用throws
  • 區別:
    • 後續程序需要繼續運行就try
    • 後續程序不需要繼續運行就throws

finally

  • finally的特點
    • 被finally控制的語句體一定會執行
    • 特殊情況:在執行到finally之前jvm退出了(比如System.exit(0))
  • finally的作用
    • 用於釋放資源,在IO流操作和數據庫操作中會見到(我們後面學習中會看到)

finally的用法很簡單,這裏就不舉例了,我們看一個關於finally典型的題

final,finally和finalize的區別?

  • final
    • 最終的意思,可以修飾類,成員變量,成員方法
    • 修飾類,類不能被繼承
    • 修飾變量,變量是常量
    • 修飾方法,方法不能被重寫
  • finally
    • 是異常處理的一部分,用於釋放資源。
    • 一般來說,代碼肯定會執行,特殊情況:在執行到finally之前jvm退出了
  • finalize
    • 是Object類的一個方法,用於垃圾回收

這個題的難點就在於finalize,我們很少了解

自定義異常

java不可能對所有的情況都考慮到,所以,在實際的開發中,我們可能需要自己定義異常。而我們自己隨意的寫一個類,是不能作爲異常類來看的,要想你的類是一個異常類,就必須繼承自Exception或者RuntimeException

/*
 * 自定義異常測試類
 */
public class StudentDemo {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入學生成績:");
        int score = sc.nextInt();

        Teacher t = new Teacher();
        try {
            t.check(score);
        } catch (MyException e) {
            e.printStackTrace();
        }
    }
}

/*
 *自定義
 */
class MyException extends Exception {
    public MyException() {
    }

    public MyException(String message) {
        super(message);
    }
}
//老師類
class Teacher {
    public void check(int score) throws MyException {
        if (score > 100 || score < 0) {
            throw new MyException("分數必須在0-100之間");
        } else {
            System.out.println("分數沒有問題");
        }
    }

運行程序,我們在控制檯輸出一個大於100的數,就會有異常
這裏寫圖片描述
是不是感覺很好玩呢

異常注意事項

我們來學習最後一個知識點

  • 子類重寫父類方法時,子類的方法必須拋出相同的異常或父類異常的子類。
  • 如果父類拋出了多個異常,子類重寫父類時,只能拋出相同的異常或者是他的子集,子類不能拋出父類沒有的異常
  • 如果被重寫的方法沒有異常拋出,那麼子類的方法絕對不可以拋出異常,如果子類方法內有異常發生,那麼子類只能try,不能throws

好了,異常我們就瞭解這麼多吧,我們要領悟java的思想

歡迎有興趣的同學加我朋友的QQ羣:點擊直接加羣555974449 請備註:java基礎再回首我們一起來玩吧。

發佈了39 篇原創文章 · 獲贊 84 · 訪問量 12萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章