一:異常捕獲
疑問(wèn): 下面的信息是通過(guò)printStackTrace方法打印出來(lái),那么異常對(duì)象從何而來(lái)呢?
Exception in thread "main" java.lang.ArithmeticException: / by zero at Demo10.div(Demo10.java:10)
at Demo10.main(Demo10.java:5)
jvm運(yùn)行到a/b這個(gè)語(yǔ)句的時(shí)候,發(fā)現(xiàn)b為0,除數(shù)為0在我們現(xiàn)實(shí)生活中是屬于不正常的情況,jvm一旦發(fā)現(xiàn)了這種不正常的情況時(shí)候,那么jvm就會(huì)馬上創(chuàng)建一個(gè)對(duì)應(yīng)的異常對(duì)象,并且會(huì)調(diào)用這個(gè)異常對(duì)象 的printStackTrace的方法來(lái)處理。
二:異常的處理
- 方式一:捕獲處理
捕獲處理的格式:
try{
可能發(fā)生異常的代碼;
}catch(捕獲的異常類型 變量名){
處理異常的代碼....
}
捕獲處理要注意的細(xì)節(jié):
- 如果try塊中代碼出了異常經(jīng)過(guò)了處理之后,那么try-catch塊外面的代碼可以正常執(zhí)行。
- 如果try塊中出了異常的代碼,那么在try塊中出現(xiàn)異常代碼后面的代碼是不會(huì)執(zhí)行了。
- 一個(gè)try塊后面是可以跟有多個(gè)catch塊的,也就是一個(gè)try塊可以捕獲多種異常的類型。
- 一個(gè)try塊可以捕獲多種異常的類型,但是捕獲的異常類型必須從小到大進(jìn)行捕獲,否則編譯報(bào)錯(cuò)。
疑問(wèn)一 : 異常的處理感覺(jué)沒(méi)有多大作用,因?yàn)槎际禽敵鲆粋€(gè)話而已?
異常處理非常有用,只不過(guò)是由于我們目前所接觸的知識(shí)點(diǎn)太過(guò)于局限而已。
疑問(wèn)二: 以后捕獲處理 的時(shí)候是否就是捕獲Exception即可?
錯(cuò)的,因?yàn)槲覀冊(cè)诂F(xiàn)實(shí)開(kāi)發(fā)中遇到不同的異常類型的時(shí)候,我往往會(huì)有不同 的處理方式。
所以要分開(kāi)不同的異常類型處理。
class Demo10
{
public static void main(String[] args)
{
int[] arr = null;
div(4,0,arr);
}
public static void div(int a , int b,int[] arr){
int c = 0;
try{
c = a/b; //jvm在這句話的時(shí)候發(fā)現(xiàn)了不正常的情況,那么就會(huì)創(chuàng)建一個(gè)對(duì)應(yīng)的異常對(duì)象。
System.out.println("數(shù)組的長(zhǎng)度:"+ arr.length); //不會(huì)被執(zhí)行
}catch(ArithmeticException e){
//處理異常的代碼....
System.out.println("異常處理了....");
System.out.println("toString:"+ e.toString());
}catch(NullPointerException e){
System.out.println("出現(xiàn)了空指針異常....");
}catch(Exception e){
System.out.println("我是急診室,包治百病!");
}
System.out.println("c="+c);
}
}
三:異常拋出
異常的處理方式----拋出處理
拋出處理(throw throws)
拋出處理要注意的細(xì)節(jié):
- 如果一個(gè)方法的內(nèi)部拋出了一個(gè)異常 對(duì)象,那么必須要在方法上聲明拋出。
- 如果調(diào)用了一個(gè)聲明拋出異常 的方法,那么調(diào)用者必須要處理異常。
- 如果一個(gè)方法內(nèi)部拋出了一個(gè)異常對(duì)象,那么throw語(yǔ)句后面的代碼都不會(huì)再執(zhí)行了(一個(gè)方法遇到了throw關(guān)鍵字,該方法也會(huì)馬上停止執(zhí)行的)。
- 在一種情況下,只能拋出一種類型異常對(duì)象。
- 某函數(shù)如果不打算處理異常,那么只需要聲明拋出的異常類型即可
throw 與throws兩個(gè)關(guān)鍵字:
- throw關(guān)鍵字是用于方法內(nèi)部的,throws是用于方法聲聲明上的。
- throw關(guān)鍵字是用于方法內(nèi)部拋出一個(gè)異常對(duì)象的,throws關(guān)鍵字是用于在方法聲明上聲明拋出異常類型的。
- throw關(guān)鍵字后面只能有一個(gè)異常對(duì)象,throws后面一次可以聲明拋出多種類型的 異常。
疑問(wèn):何時(shí)使用拋出處理?何時(shí)捕獲處理?原則是如何?
如果你需要通知到調(diào)用者,你代碼出了問(wèn)題,那么這時(shí)候就使用拋出處理.
如果代碼是直接與用戶打交道遇到了異常千萬(wàn)不要再拋,再拋的話,就給了用戶了。這時(shí)候就應(yīng)該使用捕獲處理。
class Demo11
{
public static void main(String[] args)
{
try{
int[] arr = null;
div(4,0,arr); //調(diào)用了一個(gè) 聲明拋出異常類型 的方法
}catch(Exception e){
System.out.println("出現(xiàn)異常了...");
e.printStackTrace();
}
}
public static void div(int a, int b,int[] arr) throws Exception,NullPointerException {
div2(a,b,arr);
/*不想處理異常,那么只需要聲明拋出的異常即可*/
}
public static void div2(int a, int b, int []arr) throws Exception,NullPointerException { //聲明可能拋出的異常類型
if(b==0){
throw new Exception(); //拋出一個(gè)異常對(duì)象...
//throw new ClassCastException() 不會(huì)被執(zhí)行
}else if(arr==null){
throw new NullPointerException();
}
//如果執(zhí)行了throw XXX 那么下面的語(yǔ)句不會(huì)被執(zhí)行
int c = a/b;
System.out.println("c="+c);
}
}
四:自定義異常類
自定義異常類的步驟:
1.自定義一個(gè)類且繼承自Exception類
2.重寫一個(gè)帶參(String)的構(gòu)造方法,且調(diào)用父類該構(gòu)造方法
package Test0721;
class NoMoneyException extends Exception{
public NoMoneyException(String str){ //打印異常的對(duì)象時(shí)會(huì)顯示出str
super (str); //調(diào)用父類構(gòu)造方法
}
}
public class Test01 {
public static void main(String[] args) {
try {
piaoji(9);
}catch(NoMoneyException e){
e.printStackTrace();
System.out.println("來(lái)人吶,把這小子給閹了!");
}
}
public static void piaoji(int money)throws NoMoneyException{
if (money<10){
throw new NoMoneyException("有人piaoji沒(méi)給錢.......");
}else{
System.out.println("客官,如花已經(jīng)在等您很久了.....");
}
}
}
個(gè)人總結(jié):
異常體系
Exception是編譯型異常,在編譯的時(shí)候就必須處理這些異常,要么使用try...catch捕捉,要么使用throws聲明異常拋出
public static void main(String[] args) throws FileNotFoundException {
FileInputStream input = new FileInputStream("F:/a.txt");
}
Exception下的RuntimeException是運(yùn)行時(shí)異常,就是可以處理也可以不處理,處理的話可以使用try...catch來(lái)捕捉也可以使用throw關(guān)鍵字拋出可能出現(xiàn)的異常,如果使用throw拋出異常那么同時(shí)也必須在該函數(shù)中用throws關(guān)鍵字聲明該函數(shù)會(huì)拋出異常
public static void main(String[] args) {
try{
System.out.println(1/0);
}catch (Exception e){
System.out.println("可捕捉也可不捕捉");
}
}