異常
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支援多繼承嗎? 不支援,但是可以通過接口繼承接口的方式實作類似多繼承的效果