Java如何模擬現實生活的不正常數據(1)——異常

一、異常概述

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

於是控制檯出現了

	Exception in thread "main" java.lang.ArithmeticException: / by zero
		at com.javase.excepetion.ExceptionTest01.main(ExceptionTest01.java:7)

這個信息被我們稱爲異常信息,這個信息是JVM打印的。

(1)什麼是異常,有什麼用?

一下程序執行過程中發生了不正常的情況,而這種不正常的情況叫做:異常。java語言是很完善的語言,提供了異常的處理方式,以下程序執行過程中出現了不正常情況,java把異常信息打印輸出到控制檯,供程序員參考,程序員看到異常信息之後,可以對程序,進行修改,讓程序更加的健壯。

(2)異常以什麼形式存在?

我們現在New一個異常

NumberFormatException n1 = new NumberFormatException("數字轉換異常");
System.out.println(n1);

於是控制檯便輸出了

java.lang.NumberFormatException: 數字轉換異常

所以我們發現異常是以類的形式存在的。

(3)異常結構圖

(4)編譯時異常和運行時異常的區別

)編譯時異常發生的概率高,運行時異常發生的概率比較低。

編譯時異常舉例:

看到外面下雨了,出門的時候已經預料到,如果不打傘,可能會生病。拿一把傘就是對

生病異常發生之前的處理方式,對於一些發生概率較高的異常,需要在運行之前對其進行預處理。

運行時異常舉例:

小明走在街上,可能會被輪子砸到。因爲這種概率低,所以沒必要對它進行預處理。

二、異常的處理方式

(1)在方法聲明的位置上,使用throws關鍵字,拋給上一級

爲什麼我的doSome()會報錯呢?

 因爲它繼承的父類這個,然而這個父類又繼承了編譯時的異常。

所以,會報錯。

(2)第二種方法:採用try…catch()的方式進行捕捉

一般不建議在main方法上使用throws,因爲這個異常如果真正發生了,一定會提供JVM,JVM只有終止。

(3)上報和捕捉的選擇

如果系統調用者來處理,則採用上拋。其他情況使用捕捉的方式。

三、異常的兩個方法

(1)getMessage()

//獲取異常簡單描述信息:這個信息實際上就是構造方法上面String參數

(2)printStackTrace();

//打印異常堆棧信息,java後臺打印異常堆棧追蹤信息的時候,採用了異步線程的方式打印的。

N1.printStackTrace();

就會打印出:

java.lang.NullPointerException: 異常
at com.javase.excepetion.ExceptionTest04.main(ExceptionTest04.java:5)

(3)如何利用異常printStackTrace()方法去調試

如何查看異常追蹤信息?如何快速調試程序?

(a)從上往下看

(b)從這裏往下看,因爲上面是SUN公司寫的一定不會有錯誤的

(c)灰色字體以上都是SUN公司編寫的,所以就不用看了。

 (d)看這藍色字體的第一個,因爲後面的藍色字體全部都是因爲第一個導致的。

 四、深入try...catch

(1)代碼執行順序

從上面的例子可以看出,如果try中的f1發生了異常,直接走的是catch裏面的方法,接着走try...catch後面的。

 (2)可以多寫幾個catch

第一個catch是對f1的處理,第二個catch是對f1.read()的處理,但是catch在多寫的時候,必須從上到下,遵循從下到大的原則。

(3)catch可以採用“|”的形式

(4)try…catch後面的會執行,不會因爲發生了異常,然後就宕機了。

public static void main(String[]args){
    try{
        m1();
        System.out.println("執行成功");
    }catch(FileNotFoundException e){
        e.printStackTrace();
    }
    System.out.println("HelloWorld");
    }

private static void m1() throws FileNotFoundException{
    m2();
   }

private static void m2() throws FileNotFoundException{
    m3();
    }

private static void m3() throws FileNotFoundException{
new FileInputStream("C:\\Users\\趙曉東\\Desktop\\jdkapi1.8_google.CHM");
}
執行成功
HelloWorld

這個說明,我不會因爲try...catch的執行,而影響後面。我HelloWorld照樣執行。

五、try...catch中可以寫finally

(1)關於try...catch中的finally子句:

(a)在finally子句中的代碼是最後執行的,並且一定會執行的,即使try語句塊中的代碼出現了異常。

  (b)finally語句通常使用在哪些情況下?

finally語句塊中完成資源的釋放/關閉,因爲finally中的代碼比較有保障,即使try語句塊中的代碼出現了異常,finally中的代碼也會正常執行。

try{
//首先創建一個流對象。
    FileInputStream f1 = new FileInputStream("C:\\Users\\趙曉\\Desktop\\jdkapi1.8_google");
//這時候s會出現空指針異常。
    String s =null;
    System.out.println(s.toString());
    f1.close();
}catch(FileNotFoundException e){
    e.printStackTrace();
}catch(IOException e){
    e.printStackTrace();
}

分析以上程序,f1.close()是在String s=null;之後,如果String s=null;發生了空指針異常之後,fl.close();就不會執行了,這時候流不關閉,會浪費很大的內存。

所以根據以上條件,這時候就要使用finally語句了,也就是不論上面是否執行,我一定會執行我的finally語句。下面語句是我更改之後的。

(2)try和finally,沒有catch行嗎?

行,但是try不能單獨使用。

 

從上面可以看出執行順序是:先執行try,然後再執行finally,再執行return,所以放在finally語句中的代碼一定會執行的。

 但是,退出JVM之後,finally語句中的代碼就不執行了。

(3)關於final、finally、finalize的區別

(a)final關鍵字

final修飾的類是無法繼承的,final修飾的方法無法覆蓋,final修飾的變量不能重新賦值。

(b)finally關鍵字

和try一起聯合使用

finally語句塊中的代碼是必須執行的。 

(c)finalize標識符

是一個object類中的方法名,這個方法是由垃圾回收器GC負責調用的。 

(4)finally面試題

以下程序的結果會輸出什麼?

答案是100,你一定很糾結,那麼我們來看一下反編譯的代碼

public static int m(){
    int i =100;
    int j=i;
    i++;
    return j;
}

 

 總結:以前不知道異常是什麼,感覺特別的神奇,現在終於明白了,它就是一個普普通通的類,這個類在不合適邏輯的情況下,會報。我們也可以根據自己的業務寫異常,寫異常的時候直接繼承Exception,然後再寫兩個構造方法,其中有一個String參數的構造方法,這個構造方法其實是調用了getMessage()方法。還有就是異常的處理兩種方式,一種是上拋,一種是採用try...catch的形式進行捕捉,如果你想讓調用者處理,你就用第一種t上拋的形式,其餘都用try...catch。然後try...catch是能和finally進行試用的,比如我們在最後進行關閉資源的時候,可以把方法寫到finally裏面。

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