我們通常稱一個(gè)人不正常的時(shí)候說你有病啊,從大的范圍來講病主要有兩種病,一種不可治療塔淤,如艾滋摘昌、晚期癌癥速妖,另一種可治療高蜂,這種可治療的病又分成兩類,一種如小感冒的不需要去醫(yī)院處理罕容,另一種如闌尾炎必須去醫(yī)院處理备恤,程序中也有這種不正常的情況,
比如執(zhí)行
System.out.println(args[0]);
會(huì)報(bào)異常
···
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
at com.neusoft.test.Test.main(Test.java:8)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
如果把a(bǔ)rgs指向null锦秒,就會(huì)報(bào)如下異常
Exception in thread "main" java.lang.NullPointerException
at com.neusoft.test.Test.main(Test.java:9)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
這些不正常的情況露泊,統(tǒng)稱為異常,JAVA是面向?qū)ο蟮恼Z言旅择,任何事物都可以用類來表述惭笑,我們就用各種類來表述異常,成為異常類生真,很多異常類堆積起來沉噩,就形成JAVA異常體系,任何異常類錯(cuò)誤類都有一個(gè)父類叫Throwable柱蟀,先來看一下Throwable常用方法
toString()返回完整類名+病信息
Throwable t = new Throwable();
String s = t.toString();
System.out.println(t);
getMessage()返回創(chuàng)建Throwable對(duì)象傳入的信息
Throwable t = new Throwable();
String s = t.getMessage();
System.out.println(s);
會(huì)發(fā)現(xiàn)川蒙,輸出null,此時(shí)需要指定信息
Throwable t = new Throwable("懶癌");
String s = t.getMessage();
System.out.println(s);
printStackTrace()打印異常的棧信息
舉個(gè)例子长已,比方說看病
看肺炎畜眨,醫(yī)生會(huì)一直問到底你的病的原因,肺炎的原因就是因?yàn)闆]蓋被
public static void test(){
Throwable t = new Throwable();
t.printStackTrace();
}
test();
java.lang.Throwable
at com.neusoft.test.Test.test(Test.java:14)
at com.neusoft.test.Test.main(Test.java:11)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
現(xiàn)在术瓮,讓我們來看一看Throwable的子類
error錯(cuò)誤
演示 字節(jié)碼文件名不對(duì)就要解釋康聂,就會(huì)發(fā)生錯(cuò)誤
Error是jvm或硬件出現(xiàn)的錯(cuò)誤,一般不用編寫代碼去處理
Exception是需要代碼去進(jìn)行處理
如何區(qū)分錯(cuò)誤與異常
如果程序出現(xiàn)不正常的信息的類名是以Error結(jié)束胞四,肯定是錯(cuò)誤恬汁,如果是以Exception結(jié)束,肯定是異常
異常
public static void test(int a,int b){
int c = a/b;
System.out.println(c);
}
test(2,0);
JAVA虛擬機(jī)運(yùn)行到1/0的時(shí)候撬讽,馬上創(chuàng)建一個(gè)異常對(duì)象蕊连,并調(diào)用異常對(duì)象的printStackTrace()方法
那,出了問題總得要解決游昼,現(xiàn)在就來學(xué)習(xí)異常處理的方式
捕獲處理
try{
}catch(Exception e){
e.printStackTrace();
}
int c = 0;
try {
c = a/b;
System.out.println("哈哈哈");
int[] arr = null;
System.out.println(arr.length);
}catch(ArthmeticException e){
System.out.println(e.toString());
}catch(NullPointerException e){
System.out.println(e.toString());
}
System.out.println(c);
int c = 0;
try {
c = a/b;
System.out.println("哈哈哈");
int[] arr = null;
System.out.println(arr.length);
}catch(Exception e){
System.out.println(e.toString());
}catch(ArthmeticException e){
System.out.println(e.toString());
}catch(NullPointerException e){
System.out.println(e.toString());
}
System.out.println(c);
捕獲異常要注意的細(xì)節(jié)
1甘苍、try塊中的異常經(jīng)過處理,try塊后的代碼可以正常執(zhí)行
2烘豌、如果try塊中出現(xiàn)了異常的代碼载庭,那么try塊中異常代碼之后的代碼就不會(huì)執(zhí)行
3、一個(gè)try塊后面是可以跟多個(gè)catch塊,也就是一個(gè)try塊可以捕獲多種類型異常
4囚聚、一個(gè)try塊可以捕獲多種類型的異常靖榕,但是異常的類型必須從小到大進(jìn)行捕獲,否則編譯報(bào)錯(cuò)
疑問1:捕捕獲異常打印感覺沒多大用
異常處理非常有用顽铸,只不過我們目前接觸到的非常有限度茁计,舉例:項(xiàng)目中跳到錯(cuò)誤頁面,就用到異常處理
疑問2:以后捕獲異常就弄一個(gè)Exception就夠
開發(fā)中會(huì)遇到不同的異常類型谓松,因此就需要不同的異常處理方式
拋出處理
拋出處理要注意的細(xì)節(jié)
1星压、如果一個(gè)方法內(nèi)部拋出了異常,那么必須要在方法上聲明拋出鬼譬,就像住酒店可能會(huì)著火娜膘,所以提示,就像溫馨提示
2优质、如果調(diào)用一個(gè)聲明拋出異常的方法竣贪,那調(diào)用者必須處理
3、如果一個(gè)方法內(nèi)部拋出一個(gè)異常對(duì)象巩螃,那么throw語句后面的代碼都不會(huì)執(zhí)行演怎,該方法馬上停止
4、在一種情況下牺六,一次只能拋出一種異常對(duì)象
public static void test(int a,int b) throws Exception{
if(b == 0){
throw new Exception();
}
int c = a/b;
System.out.println(c);
}
public static void test(int a,int b,int[] arr) throws Exception{
if(b == 0||arr == null){
throw new Exception();
throw new NullPoiterException();
}
int c = a/b;
System.out.println(c);
}
throw和throws
1颤枪、throw關(guān)鍵字是用于方法內(nèi)部,throws關(guān)鍵字是用于方法聲明
2、throw關(guān)鍵字是用于方法內(nèi)部拋出一個(gè)異常對(duì)象淑际,throws關(guān)鍵字是用于方法聲明拋出異常類型
3畏纲、throw關(guān)鍵字后只能跟一個(gè)異常對(duì)象,throws關(guān)鍵字一次可以跟多個(gè)異常類型
疑問:拋出處理在何時(shí)使用
如果你要通知到調(diào)用者春缕,可以拋
如果代碼直接跟用戶打交道盗胀,千萬不要再拋,拋的話就給了用戶锄贼,應(yīng)該使用捕獲異常
自定義異常類
sun給我們提供了很多異常類票灰,用于表述異常,但還不足以表述所有異常宅荤,因此需要自定義屑迂,比如去購物,沒帶錢冯键,那就是沒帶錢異常
需求惹盼,模擬fq上線,如果沒有插上網(wǎng)線惫确,拋出沒有插上網(wǎng)線異常手报,如果插上網(wǎng)線蚯舱,就顯示好友列表
自定義異常類步驟
自定義一個(gè)類繼承Exception
需求,模擬你去吃飯掩蛤,只帶10元枉昏,不夠的情況下的異常
運(yùn)行時(shí)異常與編譯時(shí)異常
如果方法上聲明了一個(gè)運(yùn)行時(shí)異常,那么在方法上可以聲明也可以不聲明揍鸟,調(diào)用者可以處理也可以不處理兄裂,如果一個(gè)方法內(nèi)部拋出了一個(gè)編譯時(shí)異常對(duì)象,那么方法上就必須要聲明蜈亩,調(diào)用者也必須處理
RunTimeException及其子類都是運(yùn)行時(shí)異常
除了運(yùn)行時(shí)異常就是編譯時(shí)異常
異常的類型不用記
疑問:為什么jvm會(huì)如此嚴(yán)格要求編譯時(shí)異常懦窘,對(duì)運(yùn)行時(shí)異常如此寬松
運(yùn)行時(shí)異常都是好的編程習(xí)慣能避免,因此就沒有嚴(yán)格要求運(yùn)行時(shí)異常
編譯時(shí)異常是編寫代碼沒法避免稚配,比如讀寫文件,就有IOException,讀硬盤數(shù)據(jù)硬盤壞掉港华,沒法用代碼規(guī)避
finally塊
資源文件使用完一定要解除占用道川,別的程序無法對(duì)該文件進(jìn)行操作
使用finally的前提一定要使用try塊
public static void test(int a,int b) throws Exception{
try {
if (b == 0) {
return;
}
}catch(Exception e){
e.printStackTrace();
}finally {
System.out.println("執(zhí)行fianally塊");
}
}
return、throw等停止的方法都不會(huì)阻止finanlly立宜,只有當(dāng)調(diào)用System.exit()方法時(shí)才能停掉
finally塊非常適合用來釋放資源冒萄,用finally塊也肯定能釋放資源
try塊的3種組合方式
try{
}catch(){
}
try{
}catch(){
}finally{
}
try{
}finally{
}
其中,最后一種適合運(yùn)行時(shí)異常