1、生活中的異常
2鳞疲、異常
程序中出現(xiàn)的錯(cuò)誤被稱為異常罪郊。
異常可分為兩大類:編譯時(shí)異常和運(yùn)行時(shí)異常尚洽。
異常就是在程序的運(yùn)行過(guò)程中所發(fā)生的不正常的事件悔橄,它會(huì)中斷正在運(yùn)行的程序。
編譯時(shí)異常一般是指語(yǔ)法錯(cuò)誤,可以通過(guò)編譯器的提示加以修正癣疟;
運(yùn)行時(shí)異常包括:
- 運(yùn)行錯(cuò)誤:如數(shù)組下標(biāo)越界挣柬,除數(shù)為0等;
- 邏輯錯(cuò)誤:如年齡超過(guò)200歲等睛挚。
3邪蛔、發(fā)生異常的原因
多種多樣,主要有:
- 系統(tǒng)資源不可用:如內(nèi)存分配失敗扎狱,文件打開失敗侧到,數(shù)據(jù)源連接失敗等等;
- 程序控制不當(dāng):如被零除淤击,負(fù)數(shù)開方匠抗,數(shù)組下標(biāo)越界等等。
4污抬、當(dāng)異常發(fā)生時(shí)汞贸,程序一般會(huì)如下反應(yīng):
- 發(fā)生異常的部分產(chǎn)生系統(tǒng)定義的錯(cuò)誤信息;
- 程序意外終止印机,并將控制權(quán)返回操作系統(tǒng)矢腻;
- 程序中所有已分配資源的狀態(tài)保持不變,這樣將會(huì)導(dǎo)致資源泄漏射赛。
5多柑、異常處理
Java編程語(yǔ)言使用異常處理機(jī)制為程序提供了錯(cuò)誤處理的能力。
6咒劲、java異常處理機(jī)制
Throwable有兩個(gè)直接子類顷蟆,它們是:
Error類:Error類的異常通常為內(nèi)部錯(cuò)誤诫隅,因此在正常情況下并不期望用戶程序捕獲它們腐魂;
Exception類:絕大部分用戶程序應(yīng)當(dāng)捕獲的異常類的根類;
一些常用的異常類都直接或間接派生自Exception類逐纬,因此我們可以認(rèn)為絕大部分的異常都屬于Exception蛔屹。
7、Java中常見(jiàn)的異常類
8豁生、異常類中的常用方法
printStackTrace的堆棧跟蹤功能顯示出程序運(yùn)行到當(dāng)前類的執(zhí)行流程兔毒。
9、多重catch塊
有時(shí)候甸箱,在try塊中的代碼段將有可能產(chǎn)生多種不同類型的異常育叁,而我們又需要針對(duì)不同的異常類型進(jìn)行不同的處理方式,那么我們就可以使用多重catch塊芍殖,來(lái)分別捕獲不同類型的異常豪嗽。
雖然多重catch塊可以同時(shí)監(jiān)視多個(gè)不同類型的異常,但是try塊中一旦有某個(gè)異常產(chǎn)生,程序就會(huì)跳轉(zhuǎn)到與之異常類型最匹配的catch塊中執(zhí)行龟梦,然后執(zhí)行finally塊(如果有finally塊的話)或之后的語(yǔ)句隐锭;
也就是說(shuō),多重catch塊只會(huì)捕捉到最先產(chǎn)生的異常计贰,而不是把所有的異常全部捕捉完钦睡;
即:不論有多少個(gè)catch塊,最多只會(huì)執(zhí)行其中的一個(gè)躁倒;
請(qǐng)注意catch塊的書寫順序:類層次越低的越往上寫荞怒,越高的越往下寫。
10樱溉、嵌套try/catch塊
有時(shí)候挣输,整個(gè)語(yǔ)句塊可以產(chǎn)生異常,而其中的某個(gè)部分又可能產(chǎn)生另外的異常福贞,而我們需要分別進(jìn)行處理撩嚼;
這樣,就可以通過(guò)嵌套try/catch塊來(lái)完成挖帘;
嵌套try/catch塊就是在一個(gè)try/catch塊中包含有另外的try/catch塊完丽。
例1:除0錯(cuò)誤
package test;
public class TestException {
public static void main(String[] args) {
System.out.println("結(jié)果:"+ 3/0);
}
}
例2:輸入的字符和整數(shù)不匹配
package test;
import java.util.Scanner;
public class TestException {
public static void main(String[] args) {
int a = new Scanner(System.in).nextInt();
System.out.println("輸入的數(shù)字是:" + a);
}
}
例3:數(shù)組下標(biāo)越界
package test;
import java.util.Scanner;
public class TestException {
public static void main(String[] args) {
int[] b = new int[]{3,5,8};
b[3] = 7;
System.out.println("數(shù)組b編號(hào)為3的整數(shù):" + b[3]);
}
}
例4:try-catch-finally
package test;
import java.util.Scanner;
public class TestException {
public static void main(String[] args) {
try {
System.out.println("結(jié)果:"+ 3/0);
int[] b = new int[]{3,5,8};
b[3] = 7;
System.out.println("數(shù)組b編號(hào)為3的整數(shù):" + b[3]);
} catch (Exception e1) {
String m = e1.getMessage();
System.out.println("錯(cuò)誤信息:"+m);
e1.printStackTrace();
}finally{
System.out.println("你好異常");
}
}
}
11、throw
throw語(yǔ)句用于手動(dòng)拋出異常拇舀;
執(zhí)行流程將在throw語(yǔ)句后立即停止逻族,轉(zhuǎn)而尋找與之類型相匹配的catch塊。
throw語(yǔ)句的語(yǔ)法是:
throw (異常類型的實(shí)例);
例子:
// Student.java
package test;
public class Student {
int age;
public int getAge() {
return age;
}
public void setAge(int age) {
try {
if(age > 150 || age < 0) {
throw new Exception("年齡不允許大于150或者小于0");
}
this.age = age;
} catch (Exception e) {
e.printStackTrace();
}
}
}
// Test.java
package test;
public class Test {
public static void main(String[] args) {
Student stu = new Student();
stu.setAge(250);
}
}
12骄崩、throws
如果某個(gè)函數(shù)中的代碼有可能引發(fā)異常聘鳞,可以使用try/catch
塊進(jìn)行處理,這種處理方式成為“內(nèi)部處理”要拂;
如果不方便在函數(shù)內(nèi)部進(jìn)行處理抠璃,也可以將異常往函數(shù)外部傳遞,這就要使用到關(guān)鍵字throws
脱惰;
throws
用于將函數(shù)內(nèi)部產(chǎn)生的異常拋給主調(diào)函數(shù)搏嗡。
一般語(yǔ)法:
返回值類型 函數(shù)名(參數(shù)列表) throws 異常類型 {
……
}
例子:
// Student.java
package test;
public class Student {
int age;
public int getAge() {
return age;
}
public void setAge(int age) throws Exception { // 年齡賦值的方法有可能會(huì)拋出異常
this.age = age;
}
}
// Test.java
package test;
public class Test {
public static void main(String[] args) {
Student stu = new Student();
try {
// 當(dāng)調(diào)用帶有throws關(guān)鍵字的函數(shù)時(shí),則必須放在try/catch塊中進(jìn)行監(jiān)控拉一,否則編譯器將會(huì)報(bào)錯(cuò)
stu.setAge(250);
} catch (Exception e) {
e.printStackTrace();
}
}
}
// Test.java
// 同樣地采盒,如果不便進(jìn)行監(jiān)控處理,也可以繼續(xù)使用throws往外拋出異常蔚润,但不太推薦此種做法磅氨。
package test;
public class Test {
public static void main(String[] args) throws Exception {
Student stu = new Student();
stu.setAge(250);
}
}
13、自定義異常
Exception類和其子類都是系統(tǒng)內(nèi)置的異常嫡纠,這些異常不一定總能捕獲程序中發(fā)生的所有異常烦租;
有時(shí)候决瞳,我們可能要?jiǎng)?chuàng)建用戶自定義的異常類;
用戶自定義異常類應(yīng)該是Exception類的子類左权,類似于:
class MyException extends Exception{
……
}