黑馬程序員-異常處理

------- android培訓java培訓、期待與您交流! ----------

異常

就是程序運行過程中,遇到了問題,這就叫異常。

1,異常的體系

Throwable 其實應該分三種

Error
通常出現重大問題如:服務器宕機數據庫崩潰等。不編寫針對代碼對其處理。
Exception
除了 RuntimeException 和其所有子類,其他所有的異常類都是在編譯的時候必須要處理的,要麼try,要麼拋
RuntimeException
RuntimeException 和其所有的子類,都不會在編譯的時候報異常,而是在運行時報異常,這時候我們就需要回頭看看我們的代碼是否有問題,比如角標越界,空指針等

2,jvm是如何處理異常的

jvm發現運算是已經違反了數學運算規則,java將這種常見的問題進行描述,並封裝成了對象叫做ArithmeticException
當除0運算髮生後,jvm將該問題打包成了一個異常對象.
並將對象拋給調用者main函數,new ArithmeticException("/by zero");
main函數收到這個問題時,有兩種處理方式:
1,自己將該問題處理,然後繼續運行
2,自己沒有針對的處理方式,只有交給調用main的jvm來處理
jvm有一個默認的異常處理機制,就將該異常進行處理.並將該異常的名稱,異常的信息.異常出現的位置打印在了控制檯上
同時將程序停止運行
那麼jvm裏都封裝了哪些對異常的處理呢

3,處理異常處理方式

A:try...catch

格式:
    try {
        需要檢測的代碼;
    }
    catch(異常類  變量) {//異常類名 對象名= new 異常類名();
        異常處理代碼;
    }
世界上最真情的相依,就是你在try,我在catch,無論你發神馬脾氣,我都默默接受,靜靜處理

public class Demo1_Exception {

    public static void main(String[] args) {
        Demo d = new Demo();                        //創建對象
        try {
            int num = d.div(10, 0);                 //調用div方法並將10和0給方法的參數
            System.out.println(num);                //打印調用方法的結果
        } catch (Exception e) {                     //當try檢測出異常的時候,就跳到catch語句中
                                                    //接收異常Exception e =  new ArithmeticException("/ by zero");
            System.out.println(e);                  //打印異常對象的toString方法
            System.out.println(e.toString());
            System.out.println("錯了,除數爲零了"); //提示
        }
        System.out.println("11111111111111111111"); //異常處理完代碼可以繼續執行
    }

}

class Demo {
    public int div(int a,int b) {                   //a = 10,b = 0
        return a / b;                               // new ArithmeticException("/ by zero");
    }
}

try...catch(...)...finally

說一下final,finalize,finally的區別
1,final可以修飾類,可以修飾方法,可以修飾變量
2,finalize,在對象沒有更多引用,垃圾回收的時候調用
3,finally 關閉流,數據庫等,釋放資源

public class Test1 {

    /**
     * @param args
     * finally的面試題
     */
    public static void main(String[] args) {
        Test t = new Test();                        //創建對象
        int num = t.getNum();                       //調用getNum()方法
        System.out.println(num);
    }

}

class Test {
    public int getNum() {
        int x = 10;                                 
        try {
            System.out.println(1/0);                //執行1/0會出現異常,創建new ArithmetiException(\ by zero);對象
            return x;                               //return語句          
        } catch (Exception e) {
            x = 20;                                 //將x值改爲20
            return x;                               //return語句
        } finally {
            x = 30;                                 //將x值改爲30
            System.out.println("finally執行了嗎");  //輸出語句
            //return x;             finally中不要寫return語句
        }

    }
    /*
     * 當程序執行到try語句的時候,1/0違背了數學的運算規則出現異常,創建出new ArithmetiException(\ by zero)對象,程序跳轉到catch語句中
     * 當程序跳轉到catch語句中,又將x值改爲了20,遇到return語句,return語句會建立一個返回路徑,將x裏面的20相當於裝到一個箱子裏,準備返回,在返回之前
     * 看有沒有finally語句,如果有執行finally語句,但是雖然將x的值改爲了30,也不會影響到返回路徑中的值,所以最後的返回還是20
     */
}

可以有下面三種搭配形式

try...catch(...)
try...catch(...)...finally
try...finally               是不能進行異常處理的,必須拋出

B:拋出 throws throw

throws:用於標識函數暴露出的異常。thorws用在函數上,後面跟異常類名(可以由多個,隔開)。

throw:用於拋出異常對象。throw用在函數內,後面跟異常對象。new Exception();

public class Demo3_Throws {

    /**
     * @param args
     * @throws Exception 
     * try catch和throws的區別
     * 如果後續代碼想要繼續執行,只能try
     * 如果後續代碼不想繼續執行,只能throws
     * 
     * Exception 和RuntimeException的區別
     * RutimeException是運行時異常,需要程序員回來修改自己的代碼
     * Exception是編譯時異常,遇到編譯時異常,必須處理,要麼try,要麼throws(未雨綢繆異常)
     */
    public static void main(String[] args) throws Exception {
        Person p = new Person();
        p.setAge(-17);
        System.out.println(p.getAge());

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

}

class Person {
    private int age;

    public Person() {                   //alt + shift + s + c 生成空參數的構造函數
        super();

    }

    public Person(int age) {            //alt + shift + s + o 根據字段生成有參數的構造函數
        super();
        this.age = age;
    }

    public int getAge() {               //alt + shift + s + r 生成set和get方法
        return age;
    }

    public void setAge(int age) throws Exception {
        if(age > 0 && age < 200) {
            this.age = age;
        }else {
            /*Exception e = new Exception("年齡非法");
            throw e;*/
            throw new Exception("年齡非法");                    //用異常處理
            //System.out.println("年齡非法");                   //以前是這樣處理的
        }
        /*
         * throw和throws的區別
         * throw寫在方法內,後面跟的是異常對象
         * throws寫在方法上,後面跟的是異常類名
         */
    }

    @Override
    public String toString() {          //alt + shift + s + s 生成toString方法
        return "Person [age=" + age + "]";
    }
}

C:到底用誰?

你能處理,建議處理。try...catch...finally
你處理不了,拋出。
在實際開發中,是分層開發,底層代碼是能拋出儘量拋出,用日誌記錄住異常信息,並提供解決方案 

4,異常體系常見方法

A:getMessage() :返回此 throwable 的詳細消息字符串。
class Throwable {
    String detailMessage;
    Throwable(){}

    Throwable(String message) {
        this.detailMessage = message;
    }

    public String getMessage() {
        return detailMessage;
    }
}
B:toString():獲取異常類名和異常信息,返回字符串。
C:printStackTrace():獲取異常類名和異常信息,以及異常出現在程序中的位置。返回值void。

5,自定義異常

 自定義類繼承Exception或者其子類(RuntimeException)

    class MyException extends Exception{
        MyException(){}

        MyException(String message){
            super(message); //將信息傳遞給父類,調用父類封裝好的構造方法
        }
    }

    class Student {
        public void giveAge(int age) throws MyException {
            if(age>40 || age<16) {
                //throw new MyExcetpion("建議不學了");
                MyExcepiont my = new MyExcetpion("建議不學了");
                throw my;
            }
            else {
                System.out.println("可以學習Java");
            }
        }
    }
E:RuntimeException和Exception
    區別:RuntimeException就是要你改代碼的。你可以不處理。

6,異常總結

RuntimeException以及其子類如果在函數中被throw拋出,可以不用在函數上聲明。
子類覆蓋父類方法時,子類的方法必須拋出相同的異常或父類異常的子類。(父親壞了,兒子不能比父親更壞)
如果父類拋出了多個異常,子類覆蓋父類時,只能拋出相同的異常或者是他的子集,子類不能拋出父類沒有的異常
如果被覆蓋的方法沒有異常拋出,那麼子類的方法絕對不可以拋出異常,如果子類方法內有異常發生,那麼子類只能try,不能throws
當try對應多個catch時,最頂層的異常要放在最下面,反過來分析如果最頂層的異常放在第一行,那根據多態原理,後面的catch就沒用了,一般面試的時候會這麼問,開發的時候不會拋有繼承關係的異常


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章