異常概述
什么是異常(Exception:Java在運行過程當中出現(xiàn)的錯誤
Throwable
類是 Java 語言中所有錯誤或異常的超類藻雪。
異常:分為運行時異常和編譯時異常,我們需要了解的是運行時異常
JVM異常處理方式
JVM是怎么處理異常的
main收到這個異常時,會做兩種處理方式
1.自己來去處理
2.自己處理不了,交給調(diào)用者jvm來處理
JVM內(nèi)部會有一個異常處理機制,會把異常的名稱,異常信息輸出到控制臺(創(chuàng)建一個異常對象)
new ArithmeticException("/by zero");
try_catch處理異常
自己處理異常
1.try...catch...finally
基本格式:
try {
可能出現(xiàn)異常的代碼
}catch(異常類型){
}finally {
處理完異常最后做的處理
}
Try:用來檢測異常
Catch:用來捕獲異常
Finally:釋放資源
try {
int a = 10 / 0;
System.out.println(a);
} catch (ArithmeticException a) {
System.out.println(a);//java.lang.ArithmeticException: / by zero
System.out.println("除數(shù)不能為0");
}
10/0;會創(chuàng)建一個異常對象
new ArithmeticException("/by zero");賦值給a,int a 接收不了,
此時就把異常對象傳給catch當中的參數(shù)a,能夠接收,就會執(zhí)行了catch當中的內(nèi)容,程序也沒有終止
只有在try出現(xiàn)問題的時候才會執(zhí)行catch當中的內(nèi)容
出現(xiàn)問題的時候catch處理完畢之后,后續(xù)的代碼繼續(xù)執(zhí)行
處理多個異常
try...catch處理多個異常
在try當中可能會出現(xiàn)不同的異常類型,此時可以使用多個catch來進行處理
try {
int[] arr = { 10, 20, 30 };
System.out.println(arr[4]);// ArrayIndexOutOfBoundsException
int a = 10 / 0;// ArithmeticException
// 在try當中出現(xiàn)了異常,會立馬停止執(zhí)行了try當中后續(xù)的代碼
// 出現(xiàn)異常時會立馬跳到catch
System.out.println("aaa");
System.out.println("aaa");
} catch (ArithmeticException a) {
System.out.println("算數(shù)異常");
} catch (ArrayIndexOutOfBoundsException arr) {
System.out.println("數(shù)組越界異常");
}catch(Exception e) {
System.out.println("其他異常");
}
Exception e不能寫在最上面,寫在上面會報錯,因為下面的永遠不會執(zhí)行到,最常用的
不知道報什么異常的時候,可以寫成
try {
int[] arr = { 10, 20, 30 };
System.out.println(arr[4]);// ArrayIndexOutOfBoundsException
int a = 10 / 0;// ArithmeticException
} catch(Exception e) {
System.out.println("其他異常");
}
JDK7之后處理多個異常
try {
int[] arr = { 10, 20, 30 };
System.out.println(arr[4]);// ArrayIndexOutOfBoundsException
int a = 10 / 0;// ArithmeticException
System.out.println("aaa");
System.out.println("aaa");
//從jdk7之后可以這樣寫
} catch (ArithmeticException | ArrayIndexOutOfBoundsException e) {
System.out.println("除數(shù)不能為0或者數(shù)組越界");
}
運行時異常與編譯時異常
什么是運行時異常?
所有的RuntimeException類及其子類成為運行時異常,在編譯時不會報錯,在運行過程程序終止運行
什么是編譯時異常?
程序員必須顯示處理,否則程序就會發(fā)生錯誤無法通過編譯
編譯時異常發(fā)生的情況
FileInputStream fl = new FileInputStream("abc.txt");
運行時異常與編譯時異常的區(qū)別
運行時異常,程序員犯的錯誤,需要回來修改代碼
編譯時異常在編譯某個程序的時候,有可能會這樣那樣的錯誤,
比如文件找不到,這樣的異常就必須在編譯時處理
如果不處理就編譯不通過
try {
FileInputStream fl = new FileInputStream("abc.txt");
}catch(Exception e) {
System.out.println("發(fā)生異常了");
}
獲取異常信息
常用方法:
1.獲取異常信息
,返回字符串,參數(shù)
try {
int a = 10/0;
}catch(Exception e) {
System.out.println(e.getMessage());// / by zero
}
2.獲取異常類名
和異常信息
try {
int a = 10 / 0;
} catch (Exception e) {//Exception e = new ArithmeticException("/ by zero")
System.out.println(e.toString());//java.lang.ArithmeticException: / by zero
System.out.println(e);//java.lang.ArithmeticException: / by zero
}
3.獲取異常類名和異常信息,及異常出現(xiàn)的位置(看異常信息從下往上來去查看)
try {
int a = 10 / 0;
} catch (Exception e) {
e.printStackTrace();
}
throw拋出異常
1.拋出運行時異常,不需要處理
class Person {
private int age;
public void setAge(int age) {
if (age > 0 && age <= 150) {
this.age = age;
} else {
// 1.System.out.println("年齡不正確");
// 2.出現(xiàn)異常,終止程序運行
throw new RuntimeException("年齡不正確");
}
}
}
2.拋出編譯時異常
class Person1 {
private int age;
public void setAge(int age) throws Exception {//拋出異常
if (age > 0 && age <= 150) {
this.age = age;
} else {
// 3.編譯時異常
throw new Exception("年齡不正確");
}
}
}
拋出了一個編譯時異常,必須要得要有人處理
如果不處理,必須繼續(xù)往上拋,拋給方法調(diào)用者
Person1 per = new Person1();
per.setAge(-10);
此時由于setAge內(nèi)部拋出了一個異常,在調(diào)用該方法時必須得要處理
1.必須要處理異常
Person1 per = new Person1();
try {
per.setAge(-10);
} catch (Exception e) {
e.printStackTrace();
}
2.繼續(xù)往上拋出
自己不處理,拋給main方法調(diào)用者jvm處理,同樣是控制臺報出錯誤
public static void main(String[] args) throws Exception {
Person1 per = new Person1();
per.setAge(-10);
}
throw與throws的區(qū)別
throw:
用在方法內(nèi),跟的是異常對象名稱
只能拋出一個異常對象
表示拋出異常
throws:
用在方法生命后面,跟的是異常類名
可以跟多個異常類名,中間使用逗號隔開
表示拋出異常,由方法調(diào)用者來處理
finally
fianlly特點
:
被finally控制的語句一定會被執(zhí)行到
//只要執(zhí)行了try,就會執(zhí)行finally
try {
System.out.println(10 / 0);
} catch (Exception e) {
System.out.println("錯誤:除數(shù)不能為0");
} finally {
System.out.println("執(zhí)行了finally");
}
特殊情況
:在執(zhí)行finally之前jvm退出了
try {
System.out.println(10 / 0);
} catch (Exception e) {
System.out.println("錯誤:除數(shù)不能為0");
//System.exit(0);
return;//終止當前方法運行,是不能阻止finally
} finally {
System.out.println("執(zhí)行了finally");//exit,jvm停止了,不會執(zhí)行
}
System.out.println("end");//不會被執(zhí)行,方法已經(jīng)終止了
finally作用
:
用來釋放資源,在IO操作中經(jīng)常見到
退出程序
:
retrun,終止當前方法運行,并不能阻止finally
exit(0),jvm停止了,finally就不會執(zhí)行
finally返回值問題
int x = 10;
try {
x = 20;
System.out.println(1 / 0);
return x;
} catch (Exception e) {
x = 30;
return x;//return返回的是當時的值
} finally {//finally一般不做return,只作資源的釋放
x = 40;
}
}
System.out.println(Demo8.test());//30
自定義異常
為什么自定義異常:
系統(tǒng)自帶的異常類名稱有很多,通過類型就能看出是什么異常,算術(shù)異常,空指針異常,數(shù)組越界異常
自己也想拋出一個異常,類名是自己定義的,通過類名就能知道是什么類型的異常
自定義運行時的異常
:
1.定義一個類繼承RuntimeException
2.拋出異常時,拋出自己定義的異常類名
class AgeBoundsException extends RuntimeException{
}
throw new AgeBoundsException();
自定義編譯時異常
:
1.定義一個類繼承Exception
class AgeBoundsException extends Exception{
}
2.拋出異常時,拋出自己定義的異常類名
public static void main(String[] args) throws AgeBoundsException {
throw new AgeBoundsException();
}
以上兩種報異常的方法都是不帶參數(shù)的
找方法的eclipse的快捷鍵:Ctrl+O
自定義帶參數(shù)的異常
1.定義一個類繼承RuntimeException或者Exception
在類當中提供一個有參數(shù)的構(gòu)造方法
把參數(shù)傳給父類構(gòu)造器
class AgeBoundsException extends Exception{
AgeBoundsException(String message){
super(message);
}
}
2.拋出異常時,拋出自己定義的異常類名并且傳入對應(yīng)的參數(shù)
public static void main(String[] args) throws AgeBoundsException {
throw new AgeBoundsException("年齡出問題了");
}