1、異常(異常的概述和分類)
- A:異常的概述
- 異常就是Java程序在運行過程中出現的錯誤。
- B:異常的分類
- 通過API查看Throwable
- Error
- 服務器宕機,數據庫崩潰等
- Exception
C:異常的繼承體系 - Throwable
- Error
- Exception
- RuntimeException
2、異常(JVM默認是如何處理異常的)
- A:JVM默認是如何處理異常的
- main函數收到這個問題時,有兩種處理方式:
- a:自己將該問題處理,然後繼續運行
- b:自己沒有針對的處理方式,只有交給調用main的jvm來處理
- jvm有一個默認的異常處理機制,就將該異常進行處理.
- 並將該異常的名稱,異常的信息.異常出現的位置打印在了控制檯上,同時將程序停止運行
B:案例演示
JVM默認如何處理異常
public class Demo1_Exception {
/** * * A:JVM默認是如何處理異常的 * main函數收到這個問題時,有兩種處理方式: * a:自己將該問題處理,然後繼續運行 * b:自己沒有針對的處理方式,只有交給調用main的jvm來處理 * jvm有一個默認的異常處理機制,就將該異常進行處理. * 並將該異常的名稱,異常的信息.異常出現的位置打印在了控制檯上,同時將程序停止運行 * B:案例演示 * JVM默認如何處理異常 */ public static void main(String[] args) { //demo1(); Demo d = new Demo(); int x = d.div(10, 0); System.out.println(x); } public static void demo1() { int[] arr = {11,22,33,44,55}; //arr = null; //NullPointerException 空指針異常 System.out.println(arr[10]); //ArrayIndexOutOfBoundsException 數組索引越界異常 } } class Demo { /* * 除法運算 */ public int div(int a,int b) { //a = 10,b = 0 return a / b; // 10 / 0 被除數是10,除數是0當除數是0的時候違背了算數運算法則,拋出異常 //new ArithmeticException("/ by zero"); } }
3、異常(try…catch的方式處理異常1)
- A:異常處理的兩種方式
- a:try…catch…finally
- try catch
- try catch finally
- try finally
- b:throws
- a:try…catch…finally
- B:try…catch處理異常的基本格式
- try…catch…finally
C:案例演示
try…catch的方式處理1個異常
public class Demo2_Exception {
/** * * A:異常處理的兩種方式 * a:try…catch…finally * try catch * try catch finally * try finally * b:throws * B:try...catch處理異常的基本格式 * try…catch…finally * C:案例演示 * try...catch的方式處理1個異常 try:用來檢測異常的 catch:用來捕獲異常的 finally:釋放資源 世界上最真情的相依就是你在try我在catch,無論你發神馬脾氣,我都靜靜接受,默默處理 當通過trycatch將問題處理了,程序會繼續執行 */ public static void main(String[] args) { Demo2 d = new Demo2(); try{ int x = d.div(10, 0); System.out.println(x); }catch(ArithmeticException a) { //ArithmeticException a = new ArithmeticException(); System.out.println("出錯了,除數爲零了"); } System.out.println("1111111111111111"); } } class Demo2 { /* * 除法運算 */ public int div(int a,int b) { //a = 10,b = 0 return a / b; // 10 / 0 被除數是10,除數是0當除數是0的時候違背了算數運算法則,拋出異常 //new ArithmeticException("/ by zero"); } }
4、異常(try…catch的方式處理異常2)
A:案例演示
- try…catch的方式處理多個異常
JDK7以後處理多個異常的方式及注意事項
public class Demo3_Exception { /** * * A:案例演示 * try...catch的方式處理多個異常 * JDK7以後處理多個異常的方式及注意事項 * * 安卓,客戶端開發,如何處理異常?try{}catch(Exception e){} * ee,服務端開發,一般都是底層開發,從底層向上拋 * * try後面如果跟多個catch,那麼小的異常放前面,大的異常放後面,根據多態的原理,如果大的放前面,就會將所有的子類對象接收 * 後面的catch就沒有意義了 */ public static void main(String[] args) { //demo1(); int a = 10; int b = 0; int[] arr = {11,22,33,44,55}; //JDK7如何處理多個異常 try { System.out.println(a / b); System.out.println(arr[10]); } catch (ArithmeticException | ArrayIndexOutOfBoundsException e) { System.out.println("出錯了"); } } public static void demo1() { int a = 10; int b = 0; int[] arr = {11,22,33,44,55}; try { System.out.println(a / b); System.out.println(arr[10]); arr = null; System.out.println(arr[0]); } catch (ArithmeticException e) { System.out.println("除數不能爲零"); } catch (ArrayIndexOutOfBoundsException e) { System.out.println("索引越界了"); } catch (Exception e) { //Exception e = new NullPointerException(); System.out.println("出錯了"); } System.out.println("over"); }
}
5、異常(編譯期異常和運行期異常的區別)
A:編譯期異常和運行期異常的區別
- Java中的異常被分爲兩大類:編譯時異常和運行時異常。
所有的RuntimeException類及其子類的實例被稱爲運行時異常,其他的異常就是編譯時異常
編譯時異常
- Java程序必須顯示處理,否則程序就會發生錯誤,無法通過編譯
- 運行時異常
- 無需顯示處理,也可以和編譯時異常一樣處理
B:案例演示
import java.io.FileInputStream; public class Demo4_Exception { /** * * A:編譯期異常和運行期異常的區別 * Java中的異常被分爲兩大類:編譯時異常和運行時異常。 * 所有的RuntimeException類及其子類的實例被稱爲運行時異常,其他的異常就是編譯時異常 * 編譯時異常 * Java程序必須顯示處理,否則程序就會發生錯誤,無法通過編譯 * 運行時異常 * 無需顯示處理,也可以和編譯時異常一樣處理 * B:案例演示 * 編譯期異常和運行期異常的區別 編譯時異常也叫做未雨綢繆異常(老師自己定義的) 未雨綢繆:在做某些事情的時候要做某些準備 編譯時異常:在編譯某個程序的時候,有可能會有這樣那樣的事情發生,比如文件找不到,這樣的異常就必須在編譯的時候處理 如果不處理編譯通不過 運行時異常:就是程序員所犯得錯誤,需要回來修改代碼 */ public static void main(String[] args) { try { FileInputStream fis = new FileInputStream("xxx.txt"); } catch(Exception e) { } } }
6、異常(Throwable的幾個常見方法)
- A:Throwable的幾個常見方法
- a:getMessage()
- 獲取異常信息,返回字符串。
- b:toString()
- 獲取異常類名和異常信息,返回字符串。
- c:printStackTrace()
- 獲取異常類名和異常信息,以及異常出現在程序中的位置。返回值void。
- a:getMessage()
B:案例演示
Throwable的幾個常見方法的基本使用
public class Demo5_Throwable { /** * * A:Throwable的幾個常見方法 * a:getMessage() * 獲取異常信息,返回字符串。 * b:toString() * 獲取異常類名和異常信息,返回字符串。 * c:printStackTrace() * 獲取異常類名和異常信息,以及異常出現在程序中的位置。返回值void。 * B:案例演示 * Throwable的幾個常見方法的基本使用 */ public static void main(String[] args) { try { System.out.println(1/0); } catch (Exception e) { //Exception e = new ArithmeticException("/ by zero"); //System.out.println(e.getMessage()); //獲取異常信息 //System.out.println(e); //調用toString方法,打印異常類名和異常信息 e.printStackTrace(); //jvm默認就用這種方式處理異常 } }
}
7、異常(throws的方式處理異常)
- A:throws的方式處理異常
- 定義功能方法時,需要把出現的問題暴露出來讓調用者去處理。
- 那麼就通過throws在方法上標識。
B:案例演示
舉例分別演示編譯時異常和運行時異常的拋出
public class Demo6_Exception { /** * * A:throws的方式處理異常 * 定義功能方法時,需要把出現的問題暴露出來讓調用者去處理。 * 那麼就通過throws在方法上標識。 * B:案例演示 * 舉例分別演示編譯時異常和運行時異常的拋出 * 編譯時異常的拋出必須對其進行處理 * 運行時異常的拋出可以處理也可以不處理 * @throws Exception */ public static void main(String[] args) throws Exception { Person p = new Person(); p.setAge(-17); System.out.println(p.getAge()); } } class Person { private String name; private int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) throws AgeOutOfBoundsException { if(age >0 && age <= 150) { this.age = age; }else { //Exception e = new Exception("年齡非法"); //throw e; throw new AgeOutOfBoundsException("年齡非法"); } }
}
8、異常(throw的概述以及和throws的區別)
- A:throw的概述
- 在功能方法內部出現某種情況,程序不能繼續運行,需要進行跳轉時,就用throw把異常對象拋出。
- B:案例演示
- 分別演示編譯時異常對象和運行時異常對象的拋出
C:throws和throw的區別
- a:throws
- 用在方法聲明後面,跟的是異常類名
- 可以跟多個異常類名,用逗號隔開
- 表示拋出異常,由該方法的調用者來處理
b:throw
- 用在方法體內,跟的是異常對象名
- 只能拋出一個異常對象名
表示拋出異常,由方法體內的語句處理
public class Demo6_Exception { /** * * A:throws的方式處理異常 * 定義功能方法時,需要把出現的問題暴露出來讓調用者去處理。 * 那麼就通過throws在方法上標識。 * B:案例演示 * 舉例分別演示編譯時異常和運行時異常的拋出 * 編譯時異常的拋出必須對其進行處理 * 運行時異常的拋出可以處理也可以不處理 * @throws Exception */ public static void main(String[] args) throws Exception { Person p = new Person(); p.setAge(-17); System.out.println(p.getAge()); } } class Person { private String name; private int age; public Person() { super(); } public Person(String name, int age) { super(); this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) throws AgeOutOfBoundsException { if(age >0 && age <= 150) { this.age = age; }else { //Exception e = new Exception("年齡非法"); //throw e; throw new AgeOutOfBoundsException("年齡非法"); } }
}
- a:throws
9、異常(finally關鍵字的特點及作用)
- A:finally的特點
- 被finally控制的語句體一定會執行
- 特殊情況:在執行到finally之前jvm退出了(比如System.exit(0))
- B:finally的作用
- 用於釋放資源,在IO流操作和數據庫操作中會見到
C:案例演示
finally關鍵字的特點及作用
public class Demo7_Finally { /** * * A:finally的特點 * 被finally控制的語句體一定會執行 * 特殊情況:在執行到finally之前jvm退出了(比如System.exit(0)) * B:finally的作用 * 用於釋放資源,在IO流操作和數據庫操作中會見到 * C:案例演示 * finally關鍵字的特點及作用 *return語句相當於是方法的最後一口氣,那麼在他將死之前會看一看有沒有finally幫其完成遺願,如果有就將finally執行 *後在徹底返回 */ public static void main(String[] args) { try { System.out.println(10/0); } catch (Exception e) { System.out.println("除數爲零了"); System.exit(0); //退出jvm虛擬機 return; } finally { System.out.println("看看我執行了嗎"); } }
}
10、異常(finally關鍵字的面試題)
- A:面試題1
- final,finally和finalize的區別
B:面試題2
如果catch裏面有return語句,請問finally的代碼還會執行嗎?如果會,請問是在return前還是return後。
public class Test1 { /** * * A:面試題1 * final,finally和finalize的區別 * final可以修飾類,不能被繼承 * 修飾方法,不能被重寫 * 修飾變量,只能賦值一次 * * finally是try語句中的一個語句體,不能單獨使用,用來釋放資源 * * finalize是一個方法,當垃圾回收器確定不存在對該對象的更多引用時,由對象的垃圾回收器調用此方法。 * B:面試題2 * 如果catch裏面有return語句,請問finally的代碼還會執行嗎?如果會,請問是在return前還是return後。 */ public static void main(String[] args) { Demo d = new Demo(); System.out.println(d.method()); } } class Demo { public int method() { int x = 10; try { x = 20; System.out.println(1/0); return x; } catch (Exception e) { x = 30; return x; } finally { x = 40; //return x; 千萬不要在finally裏面寫返回語句,因爲finally的作用是爲了釋放資源,是肯定會執行的 //如果在這裏面寫返回語句,那麼try和catch的結果都會被改變,所以這麼寫就是犯罪 } } }
11、異常(自定義異常概述和基本使用)
- A:爲什麼需要自定義異常
- 舉例:人的年齡
- B:自定義異常概述
- 繼承自Exception
- 繼承自RuntimeException
C:案例演示
自定義異常的基本使用
public class Demo8_Exception { /** * * A:爲什麼需要自定義異常 * 通過名字區分到底是神馬異常,有針對的解決辦法 * 舉例:人的年齡 * B:自定義異常概述 * 繼承自Exception * 繼承自RuntimeException * C:案例演示 * 自定義異常的基本使用 */ public static void main(String[] args) { } } class AgeOutOfBoundsException extends Exception { public AgeOutOfBoundsException() { super(); } public AgeOutOfBoundsException(String message) { super(message); } }
12、異常(異常的注意事項及如何使用異常處理)
- A:異常注意事項
- a:子類重寫父類方法時,子類的方法必須拋出相同的異常或父類異常的子類。(父親壞了,兒子不能比父親更壞)
- b:如果父類拋出了多個異常,子類重寫父類時,只能拋出相同的異常或者是他的子集,子類不能拋出父類沒有的異常
- c:如果被重寫的方法沒有異常拋出,那麼子類的方法絕對不可以拋出異常,如果子類方法內有異常發生,那麼子類只能try,不能throws
B:如何使用異常處理
- 原則:如果該功能內部可以將問題處理,用try,如果處理不了,交由調用者處理,這是用throws
區別:
- 後續程序需要繼續運行就try
- 後續程序不需要繼續運行就throws
如果JDK沒有提供對應的異常,需要自定義異常。
異常(練習)
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.Scanner;
public class Test2 {
/**
* 鍵盤錄入一個int類型的整數,對其求二進制表現形式
* 如果錄入的整數過大,給予提示,錄入的整數過大請重新錄入一個整數BigInteger
* 如果錄入的是小數,給予提示,錄入的是小數,請重新錄入一個整數
* 如果錄入的是其他字符,給予提示,錄入的是非法字符,請重新錄入一個整數
*
* 分析:
* 1,創建鍵盤錄入對象
* 2,將鍵盤錄入的結果存儲在String類型的字符串中,存儲int類型中如果有不符合條件的直接報錯,無法進行後續判斷
* 3,鍵盤錄入的結果轉換成int類型的數據,是正確的還是錯誤的
* 4,正確的直接轉換
* 5,錯誤的要進行對應判斷
*/
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("請輸入一個整數:");
while(true) {
String line = sc.nextLine(); //將鍵盤錄入的結果存儲在line中
try {
int num = Integer.parseInt(line); //將字符串轉換爲整數
System.out.println(Integer.toBinaryString(num));//將整數轉換爲二進制
break; //跳出循環
}catch(Exception e) {
try {
new BigInteger(line);
System.out.println("錄入錯誤,您錄入的是一個過大整數,請重新輸入一個整數:");
}catch (Exception e2) { //alt + shif + z (try catch快捷鍵)
try {
new BigDecimal(line);
System.out.println("錄入錯誤,您錄入的是一個小數,請重新輸入一個整數:");
} catch (Exception e1) {
System.out.println("錄入錯誤,您錄入的是非法字符,請重新輸入一個整數:");
}
}
}
}
}
}