天天看點

13異常(try/catch/finally/throws/throw、自定義異常、面試題:return執行順序)異常

異常

1.try

異常被捕獲後,可以繼續執行後續代碼,如果未捕獲,就不再執行後續代碼

try: 嘗試

将可能出現異常的代碼放入try塊中,不要将過多的代碼放進try中。=,沒有閱讀性。

使用要求:try不能單獨出現,必須結合catch或者finally或者catch-finally

情景:1.出現的異常和捕獲的異常是比對的,捕獲異常,程式繼續執行,不中斷

2.出現的異常和捕獲的異常是不比對的,不會捕獲,程式中斷,不再執行

3.捕獲多個異常,多個異常寫多個catch塊,捕獲子類和父類異常時,先寫子類,後寫父類。

4.捕獲多個異常時,我們可以統一捕獲一個父類 Exception。但實際開發中不建議這樣使用,因為沒有閱讀性可言。

Throwable兩大子類: Error Exception

Exception兩種子類:

1.運作時異常(RuntimException),可處理可不處理

2.檢查(編譯時)異常,必須處理

2.catch

catch:捕獲

使用要求:不能單獨出現,必須結合try

表示捕獲到異常後将執行的處理代碼

多個異常寫多個catch塊,捕獲子類和父類異常時,先寫子類,後寫父類

3.finally

finally:最終

不管是否出現異常都執行的代碼塊,或者異常是否比對到都會執行

使用要求:不能單獨出現必須結合try,或者try-catch

适用場景:通常用于關閉資源或者一些必須執行的操作

finally不執行的唯一情況,退出JVM虛拟機·

System.exit(int status);

status:0表示正常退出,非0表示非正常退出,雖然表示的含義不同,但執行退出虛拟機的效果是一樣的(隻是為了區分jvm關閉原因)

import java.util.Scanner;
​
/**
 *  finally關鍵字  最終
 *  注意:不能單獨出現 必須結合 try-catch 或者結合try
 *  finally中的代碼 表示不管是否出現異常都執行 或者 異常是否被捕獲到都執行
 *  應用場景:當我們需要關閉一些資源的時候  
 * @author asus
 *
 */
public class Test1 {
    public static void main(String[] args) {
        try {
            Scanner in = new Scanner(System.in);
            System.out.print("請輸入被除數:");
            int num1 = in.nextInt();
            System.out.print("請輸入除數:");
            int num2 = in.nextInt();
            System.out.println(num1+"/"+ num2 +"="+ num1/ num2);
            
        }catch(ArithmeticException e) {
                e.printStackTrace();
        }finally {
            System.out.println("感謝使用本程式!");
        }
        
    }
}
           

4.throws

throws:抛的複數

使用throws聲明目前方法有可能出現的異常給調用者

使用位置:在方法形參清單小括号之後

使用方式:可聲明多個異常,使用逗号隔開

調用者處理異常的兩種情況:

  1.如果方法聲明的是運作時異常(RuntimeException),那麼調用者可處理也可不處理,編譯也不會報錯

  2.如果方法聲明的是檢查異常(CheckedException) 那麼調用者必須處理

檢查異常處理有如下兩種方式:

  1.繼續聲明給JVM虛拟機,自己不做處理

  2.加上try-catch自行處理

5.throw

throw:抛

位置:方法體内部 可作為一條單獨的語句,一條語句隻能抛出一個異常

throw throws
生成并抛出異常 聲明方法内抛出了異常
位于方法體内部,可作為單獨語句使用 必須跟在方法參數清單後面,不能單獨使用
抛出一個異常對象,且隻能是一個 聲明抛出異常類型,可以跟多個異常

6.自定義異常

當JDK提供的異常不能滿足我們的開發時,我們可以自定義異常來實作需求

1.先編寫異常類

2.繼承父類(Exception、Throwable、RuntimeException)都可以

3.編寫構造方法,傳入異常資訊

4.在代碼中抛出自定義異常

public class AgeException extends Exception{
​
    private static final long serialVersionUID = 1L; // 序列化ID 自動生成
​
    public AgeException(String message) {
        super(message);
    }
}
           
public class SexException extends RuntimeException{
​
    private static final long serialVersionUID = 1L;
    public SexException(String message) {
        super(message);
    }
}   
           
public class Person {
    private String name;
    private int age;
    private String sex;
    public int getAge() {
        return age;
    }
    public void setAge(int age) throws AgeException {
        if(age > 0 && age <= 130) {
            this.age = age;
        }else {
            throw new AgeException("年齡不合适");
        }
    }
    
    public String getSex() {
        return sex;
    }
​
    public void setSex(String sex) {
        if(sex.equals("男") || sex.equals("女")) {
            this.sex = sex;
        }else {
            throw new SexException("性别不合适");
        }
    }
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
    public static void main(String[] args) {
        Person p1 = new Person();
        try {
            p1.setAge(111);
        } catch (AgeException e) {
            e.printStackTrace();
        }
        p1.setSex("男");
    }
}
           

面試題:try-catch塊中存在return語句,是否還執行finally塊? 如果執行,說出執行順序

詳細連結:https://blog.csdn.net/zitian246/article/details/107966022 

try語句在傳回前,将其他所有的操作執行完(未考慮try出現異常的情況,出現異常時執行catch,規則與其相同),保留好要傳回的值,而後轉入執行finally中的語句,而後分為以下三種情況:

情況一:如果finally中有return語句,則會将try中的return語句"覆寫"掉(異常在傳回值之前除外,此時不執行try中的return語句),直接執行finally中的return語句,得到傳回值,這樣便無法的得到try之前保留好的傳回值

情況二:如果finally中沒有return語句,也沒有改變要傳回的值,則執行完finally中的語句後,會接着執行try中的return語句,傳回之前保留的值

情況三:如果finally中沒有return語句,但是改變了要傳回的值,這裡優點類似于引用傳遞和值傳遞的差別,分以下兩種情況:

        a)如果return的資料是基本資料類型或文本字元串,則在finally中對該基本資料的改變不起作用,try中的return語句依然會傳回進入finally塊之前保留的值

        b)如果return的資料類型是引用資料類型,而在finally中對該引用資料類型的屬性值的改變起作用,try中的return語句傳回的值就是在finally中改變後的該屬性的值。

補充:出現異常捕獲時,執行catch語句,其規則與try中相同。

任何執行try 或者catch中的return語句之前,都會先執行finally語句

 每日問題

1.異常的體系結構,寫出三個父類

2.try-catch-finally-throw-throws關鍵字分别用途是什麼?

3.RunTimeException和CheckedException有在處理上有什麼不同?

4.try-catch-finally中 如果try中已經return了值 那麼finally中對傳回值的操作會不會改變返 回值?

5.finally不執行的唯一情況是什麼?

6.繼承中實作多态的主要方式是什麼?兩種

7.throw和throws的差別

8.自定義異常的步驟

9.靜态方法中如何通路執行個體屬性和方法?

10.java支援多繼承嗎?

解答

1.異常的體系結構,寫出三個父類

     Throwable Exception Error

2.try-catch-finally-throw-throws關鍵字分别用途是什麼?

    try 可能出現異常的代碼

    catch 捕獲異常

    finally 不管是否出現異常都将執行的代碼

    throw 抛出一個異常

    throws 聲明異常,可以聲明多個

3.RunTimeException和CheckedException有在處理上有什麼不同?

    RuntimeException 不是必須處理

    CheckedException 必須處理 繼續聲明給JVM虛拟機 或者 try-catch處理

4.try-catch-finally中 如果try中已經return了值 那麼finally中對傳回值的操作會不會改變返 回值?

5.finally不執行的唯一情況是什麼?

    System.exit(int status); status 為0表示正常退出 非0 表示非正常退出 效果都一樣

6.繼承中實作多态的主要方式是什麼?兩種

    父類作為形參 父類作為傳回值

7.throw和throws的差別

    throw是在方法體内部單獨作為一條語句使用 抛出異常

    throws聲明異常,寫在形參清單之後 可以聲明多個 多個之間逗号隔開

8.自定義異常的步驟

    編寫異常類

    繼承父類(Throwable,Exception,RuntimeException)

    編寫構造方法 方法中抛出自定義異常

9.靜态方法中如何通路執行個體屬性和方法? 不能,必須先new對象,然後通過對象名. 通路

10.java支援多繼承嗎? 不支援,但是可以通過接口繼承接口的方式實作類似多繼承的效果

繼續閱讀