天天看點

Java匹馬行天下之JavaSE核心技術——異常處理Java匹馬行天下之JavaSE核心技術——異常處理

Java匹馬行天下之JavaSE核心技術——異常處理

異常的簡介

在Java中,異常就是Java在編譯、運作或運作過程中出現的錯誤。

程式錯誤分為三種:編譯錯誤、運作時錯誤和邏輯錯誤

  • 編譯錯誤是因為程式沒有遵循文法規則,編譯程式能夠自己發現并且提示我們錯誤的原因和位置,這個也是新手在剛接觸程式設計語言時經常遇到的問題。
  • 運作時錯誤是因為程式在執行時,運作環境發現了不能執行的操作。
  • 邏輯錯誤是因為程式沒有按照預期的邏輯順序執行。異常也就是指程式運作時發生錯誤,而異常處理就是對這些錯誤進行處理和控制。

下面看一段代碼:

package com.yichang;

public class Test {
    public static void main(String[] args) {
        System.out.println(1/0);//0不能做除數
    }
}           

複制

運作後的結果為:

Java匹馬行天下之JavaSE核心技術——異常處理Java匹馬行天下之JavaSE核心技術——異常處理

我們發現程式出了錯,而圖中的錯誤資訊告訴我們兩個資訊:

  • 出了什麼錯
  • 出錯的位置

異常産生的過程

以上面的代碼為例,程式在運作過程中,先運作main方法,然後執行到1/0時,程式就會報錯,程式先會建立一個錯誤對象,然後把這個錯誤對象丢出來,我們都知道我們的程式是運作在Java虛拟機(JVM)上,程式丢出來的錯誤對象就會被JVM捕獲到。當然,JVM捕獲到錯誤對象後,它也不知道該怎麼辦,它不可能幫你調錯,JVM會把錯誤資訊給你列印出來。

總結一下,就是:

  • 上例中出現的異常是運作時異常(異常是錯誤)
  • 程式會建立一個錯誤對象,然後把錯誤對象丢出來(抛異常)
  • 預設由JVM把錯誤資訊進行捕獲,列印出來(捕獲異常)

為什麼不能直接讓JVM擷取異常

先看下面代碼:

package com.yichang;

public class Test {
    public static void main(String[] args) {
        System.out.println(1/0);//0不能做除數

        System.out.println("你好");
    }
}           

複制

運作結果為:

Java匹馬行天下之JavaSE核心技術——異常處理Java匹馬行天下之JavaSE核心技術——異常處理

從上面代碼和運作結果中,我們不難看出在控制台沒有列印出你好。出現這種情況,是因為在JVM捕獲到異常後,程式會終止。換句話說,在由JVM來處理錯誤的時候,此時,程式會終止,是以異常之後的代碼就無法運作了。我們可以根據生活執行個體想想,什麼時候百度會因為搜不到東西停服務,肯定是不會的,是以我們後面要做的就是如何在異常到達JVM之前把異常攔下來,自己單獨處理,就不要麻煩JVM了。

異常的分類

在上面執行個體中我說過程式會建立錯誤對象,說到對象,我們都知道對象是由類建立的,那異常對象肯定是通過異常類來建立的。下面圖中就是Java給我們提供的異常類:

Java匹馬行天下之JavaSE核心技術——異常處理Java匹馬行天下之JavaSE核心技術——異常處理
Java匹馬行天下之JavaSE核心技術——異常處理Java匹馬行天下之JavaSE核心技術——異常處理

從圖中我們能看出Throwable是所有異常的根,所有的異常類都繼承自Throwable,就像面向對象裡面所有的類都繼承自Object。

下面我來說一下異常的分類:

  • RuntimeException:運作時異常,一般不手動處理,出問題了再處理。
  • 其他Exception:必須要經過手動處理。
  • Error:一般指的是系統級錯誤。

我再用生活例子解釋一下這三種異常,便于新手了解: 假設我們現在開車上山,

  • 開車的過程中發現山上有許多小石頭,但我們不可能把所有小石頭都處理了,這時候我們依舊正常開,什麼時候小石頭把車胎給弄壞了,我們再下來,換備胎,這就是運作時異常
  • 開車的過程中發現前面有一個很大的石頭擋住了路,這時候你必須下車先把這石頭挪走,你才能繼續上山,這也就是其他Exception。
  • 開車上山的過程中山塌陷了,你又無法處理,必須要等到山好了你才能繼續出發,也就是Error,就是這種錯誤我們一般的程式員是處理不了的。

異常的處理方法

try···catch處理

文法:

try{
    //嘗試執行的代碼
        }catch(Exception e){

    //處理異常的代碼
        }finally{

    //最終的
        }           

複制

下面我将文中案例進行改造:

package com.yichang;

public class Test {
    public static void main(String[] args) {
        try {
            System.out.println(1/0);//0不能做除數
        }catch (Exception e){
            e.printStackTrace();//列印錯誤資訊,給程式員看的
            System.out.println("系統出現錯誤,請聯系管理者");//給客戶看的
        }finally {

            //一般做收尾工作
            System.out.println("你好");
        }

    }
}           

複制

運作結果為:

Java匹馬行天下之JavaSE核心技術——異常處理Java匹馬行天下之JavaSE核心技術——異常處理
  • try-- 用于監聽。将要被監聽的代碼(可能抛出異常的代碼)放在try語句塊之内,當try語句塊内發生異常時,異常就被抛出。
  • catch-- 用于捕獲異常。catch用來捕獲try語句塊中發生的異常。
  • finally-- finally語句塊總是會被執行。它主要用于回收在try塊裡打開的物力資源(如資料庫連接配接、網絡連接配接和磁盤檔案)。

throws和throw處理

  • throws表示方法準備要扔出來一個異常
  • throw表示向外抛出異常

舉例說明:

package com.yichang;

public class Test1 {

    public static void chu(int a,int b) throws Exception{
        if (b==0){
            throw new Exception("除數不能為0");
        }else {
            System.out.println(a/b);
        }
    }

    public static void main(String[] args) throws Exception{

        chu(1,0);
    }
}           

複制

運作結果:

Java匹馬行天下之JavaSE核心技術——異常處理Java匹馬行天下之JavaSE核心技術——異常處理

以上這兩種方法都是處理異常的,如果這個異常你可以處理,就用try···catch方法捕獲并處理異常,如果這個異常你不能處理,就用throws方法抛出異常,但作為程式員的我們要始終記住一句話:産生的錯誤盡可能的自己處理,少向外抛出異常。

自定義異常

到這可能有的朋友要問了,為什麼要自定義異常,Java給的那麼多還不夠用嗎?我可以告訴你,當然不夠用,比如在生活中,我們都知道外面的澡堂子裡邊是分男女澡堂的,如果有男顧客走進了女澡堂或有女顧客走進了男澡堂,就壞事了,這算是一個大異常吧,那大家想,jdk會給我們提供跟性别還有澡堂子有關的異常嗎?肯定是不可能的,那此時就需要我們自定義異常。我以澡堂子為例,寫一個程式,供大家參考。

自定義異常:直接繼承Exception或者RuntimeException來是實作自定義異常

Person類

package com.yichang;

public class Person {
    String name;//姓名
    String gender;//性别

    public Person(String name, String gender) {
        this.name = name;
        this.gender = gender;
    }
}           

複制

ZaoTangZi類

package com.yichang;

public class ZaoTangZi {
    public void man(Person p) throws GenderException{
        if (p.gender=="男"){
            System.out.println("歡迎光臨");
        }else {
            //需要抛出一個異常
            throw new GenderException("性别錯誤,這裡是男澡堂子");
        }
    }
}           

複制

GenderException類

package com.yichang;

public class GenderException extends Exception{
    //自己定義的異常必須要繼承Exception或RuntimeException

    public GenderException(String msg){
        super(msg);//調用父類的構造方法,Exception(msg)
    }
}           

複制

Test類

package com.yichang;

public class Test {
    public static void main(String[] args) throws GenderException{
        Person p1 = new Person("張三","男");
        Person p2 = new Person("小花","女");

        ZaoTangZi z = new ZaoTangZi();
        z.man(p2);
    }
}           

複制

運作結果:

Java匹馬行天下之JavaSE核心技術——異常處理Java匹馬行天下之JavaSE核心技術——異常處理

總結

寫到這,這篇異常處理的文章就寫完了,看完後我們應該明白以下幾個問題:

  • 什麼是異常
  • 出現異常如何處理
  • 如何自定義異常

可能寫的有點啰嗦了,但對新手是友好的,還請大家多多包涵,希望能對大家有所幫助。