1. 程式人生 > >章節六、1-異常---編譯時會被檢測的

章節六、1-異常---編譯時會被檢測的

一、異常其實就是將問題封裝成物件並拋給呼叫者,異常的出現是為了提高程式的健壯性而將問題描述出來。

java分兩個時期,一個叫編譯時期,一個叫執行時期,編譯時期就是說檢查語法錯誤,也就是原始碼有沒有寫錯,如果原始碼沒寫錯,生成的.class檔案在執行時期出錯,這些情況就叫異常。

二、新建兩個類,類名為ExceptionsDemo和Account,使用丟擲異常的方式來處理異常。

1、在Account這個類中寫一個“取錢”的功能

package introduction8;

/*匯入包為
 * import java.sql.Connection;
 * 將Connection改為*後,這樣就能一次性將sql這個包中的所有類
*/ import java.sql.Connection; import java.sql.DriverManager; public class Accout { /* 在取錢之前,程式要訪問資料庫,提供賬號資訊、餘額進行運算,然後判斷能不能取出錢, * 因此需要先寫一個能丟擲異常,顯示異常的功能, * 因為要建立一個數據庫連結,使用mysql為例 */ public Connection getConn() { //Connection為引用型變數,預設值為空,用於與特定資料庫進行連線, //他是一個介面,我們需要用到Connection連結 Connection conn = null
; //定義連線資料庫需要用到的引數 /*因為使用mysql資料庫,所以使用jdbc,表示java資料庫連線, * 是一種用於執行sql語句的java api,jdbc是java資料庫的標準, * 提供了一種讓java程式連線到資料庫的機制,如果要使用jdbc連線到資料庫, * 必須要使用jdbc驅動程式。 * (本機還未安裝資料庫,此處目的是為了演示異常,所以執行時會報異常) */ String url = "jdbc:mysql://localhost:3306/"; String user
= "user"; String password = "code"; //Connection是一個靜態方法,所以能夠直接呼叫,建立資料庫連線 conn = DriverManager.getConnection(url, user, password); return conn; } public void withdraw(int money) { } }

在eclipse中conn = DriverManager.getConnection(url, user, password);程式碼報錯,

這裡會報異常是因為Connection介面中有檢查異常的機制,所以此處報出了sql異常

2、因為在getConn方法中有異常所以,在這個方法上要有throws宣告出來,不然編譯會失敗,宣告的目的是為了讓呼叫這個getConn方法的人去處理,如果呼叫者也不處理的話,編譯還是會失敗的,在eclipse中滑鼠移動到報錯的程式碼上,會給出上圖中兩次解決方式(throws丟擲異常,try/catch捕獲並處理異常),這裡選擇第一種,直接丟擲異常,讓呼叫者自己解決。

3、選擇丟擲異常後在其它方法中呼叫,直接呼叫時會報異常,這就是前面提到的,如果呼叫者不處理的話,編譯還是會報錯。然後繼續給呼叫的方法宣告丟擲異常。

4、在ExceptionsDemo類中呼叫

package introduction8;

/*
 * 執行時會發生的問題分兩類:
 * 1、exception異常:
 * 這種異常是可處理的,java虛擬機器是用來解釋並執行java程式的應用軟體,
 * 這種是異常直接從java虛擬機發生的,是java虛擬機器在執行過程中發生的問題,
 * 並告訴給使用者,對異常可以進行鍼對性處理。
 * exception異常分兩種:
 * a、編譯時檢查的異常,先檢查語法的問題,語法都對的情況下再檢查語法的安全問題。
 * 對於編譯時被檢查的異常,功能如果有問題,當功能中又未宣告的話,就會報錯並且不會讓程式執行通過。
 * b、執行時異常,執行時異常編譯器是不檢查
 * 如果程式碼中有零做為除數,編譯時是不會檢查該異常的,執行時才會報錯,也就是說除數為零,程式碼的語法
 * 和功能是沒有問題的,只不過傳的引數有問題。另外就是數值角標越界的情況,例如數值的長度為3,
 * 角標就是0、1、2這3個數,想訪問角標為3的元素,編譯時不會報錯,執行時報錯,因為3這個元素根本不存在。
 * 2、Error錯誤:
 * Error發生是不處理的,error是由系統底層發生的,底層告訴了java虛擬機器的,java虛擬機器告訴使用者,
 * 例如記憶體溢位,一旦發生error了,必須修改程式碼,對異常本身不做針對性處理。
 */

//因為用的IDE整合開發環境,都是可以檢查編譯時異常,異常的部分會先紅色波浪線和紅叉圖示
public class ExceptionsDemo {

    public static void main(String[] args) {
        
        Accout acc = new Accout();
        acc.withdraw(100);
    }

}

呼叫後傳參仍然報異常:

繼續選擇宣告異常,點選執行,控制檯提示異常

三、使用try/catch捕獲異常

package introduction8;

import java.sql.SQLException;

/*
 * 執行時會發生的問題分兩類:
 * 1、exception異常:
 * 這種異常是可處理的,java虛擬機器是用來解釋並執行java程式的應用軟體,
 * 這種是異常直接從java虛擬機發生的,是java虛擬機器在執行過程中發生的問題,
 * 並告訴給使用者,對異常可以進行鍼對性處理。
 * exception異常分兩種:
 * a、編譯時檢查的異常,先檢查語法的問題,語法都對的情況下再檢查語法的安全問題。
 * 對於編譯時被檢查的異常,功能如果有問題,當功能中又未宣告的話,就會報錯並且不會讓程式執行通過。
 * b、執行時異常,執行時異常編譯器是不檢查
 * 如果程式碼中有零做為除數,編譯時是不會檢查該異常的,執行時才會報錯,也就是說除數為零,程式碼的語法
 * 和功能是沒有問題的,只不過傳的引數有問題。另外就是數值角標越界的情況,例如數值的長度為3,
 * 角標就是0、1、2這3個數,想訪問角標為3的元素,編譯時不會報錯,執行時報錯,因為3這個元素根本不存在。
 * 2、Error錯誤:
 * Error發生是不處理的,error是由系統底層發生的,底層告訴了java虛擬機器的,java虛擬機器告訴使用者,
 * 例如記憶體溢位,一旦發生error了,必須修改程式碼,對異常本身不做針對性處理。
 */

//因為用的IDE整合開發環境,都是可以檢查編譯時異常,異常的部分會先紅色波浪線和紅叉圖示
public class ExceptionsDemo {

    public static void main(String[] args){
        
        Accout acc = new Accout();
        try {
        /*把可能出現異常的程式碼反正try/catch這個大括號裡面,
         * 如果try裡面的語句有異常,就回去執行catch裡面的語句
         */
            acc.withdraw(100);
        } catch (SQLException e) {
        //將異常資訊封裝成物件並列印
            e.printStackTrace();
        }
    }

}

執行後的結果:

如果想自定義只打印錯誤資訊:

四、catch不能離開try單獨使用。

try語句可以沒有catch,當try語句不能單獨執行,如果沒有catch就必須要與finally一起使用。

五、finally{}放在finally中的語句一定會被執行

六、try是如何工作的?

1、在try中新增如下兩行程式碼,以便於我們能直觀的看到try是如何執行的

結果:

直接跳過列印“執行withdraw”這條命令語句,執行catch和finally中的語句,這是因為try中有異常

2、註釋未處理前報異常的程式碼

點選執行:

跳過了catch中的語句,只執行了try和finally中的語句,這是因為try中沒有異常

7、try與finally一起使用,沒有catch

這是在不一定要處理異常,但是有資源需要釋放的情況下使用。

註釋掉catch,然後執行

執行成功:

finally語句塊中可以放釋放資源的語句,例如斷開資料庫連線,有時候程式出現異常,資源是來不及釋放的,而如果把資源放在finally中,就可以得到釋放,因為finally中的語句是肯定會被執行的。