更新時(shí)間:2019-08-28 11:37:03 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽2917次
動(dòng)力節(jié)點(diǎn)java學(xué)院小編介紹的“java異常處理機(jī)制詳解”的內(nèi)容太長(zhǎng),上文鏈接請(qǐng)看:http://www.soulsinkind.com/javazixun/1654.html
Checked異常和Runtime異常體系
java異常被分為兩大類:Checked異常和Runtime異常(運(yùn)行時(shí)異常)。
所有RuntimeException類及其子類的實(shí)例被稱為Runtime異常,不是RuntimeException類及其子類的異常實(shí)例則被稱為Checked異常。
只有java語(yǔ)言提供了Checked異常,其他語(yǔ)言都沒(méi)有提供,java認(rèn)為Checked異常都是可以被處理(修復(fù))的異常,所以java程序無(wú)須顯式的處理Checked異常。如果程序沒(méi)有處理Checked異常,該程序在編譯時(shí)就會(huì)發(fā)生錯(cuò)誤,無(wú)法通過(guò)編譯。
Checked異常的處理方式:
(1)當(dāng)方法明確知道如何處理異常,程序應(yīng)該使用try...catch塊來(lái)捕獲該異常,然后在對(duì)應(yīng)的catch塊中修補(bǔ)該異常。
(2)當(dāng)方法不知道如何處理異常,應(yīng)該在定義該方法時(shí)聲明拋出該異常。
Runtime異常無(wú)須顯式聲明拋出,如果程序需要捕捉Runtime異常,也可以使用try...catch塊來(lái)捕獲Runtime異常。
問(wèn)題是:大部分的方法總是不能明確知道如何處理異常,這就只能聲明拋出異常了。
使用throws拋出異常
使用throws拋出異常的思路是:當(dāng)前方法不知道如何處理這種類型的異常,該異常應(yīng)該由上一級(jí)調(diào)用者處理,如果main方法也不知道應(yīng)該如何處理這種類型的異常,也可以使用使用throws聲明拋出異常,該異常將交給JVM來(lái)處理。
JVM對(duì)異常的處理方法:打印異常跟蹤棧的信息,并終止程序運(yùn)行,所以有很多程序遇到異常后自動(dòng)結(jié)束。
使用throws拋出異常的格式:
throws聲明的拋出的語(yǔ)法格式緊跟在方法之后,可以聲明多個(gè)異常類,多個(gè)異常類之間以逗號(hào)隔開(kāi)。一旦使用了throws語(yǔ)句聲明拋出異常,就不用再使用try...catch來(lái)捕獲異常了。
如:throws ExceptionClass1,ExceptionClass2...
注意點(diǎn)1:如果某段代碼調(diào)用了一個(gè)帶throws聲明的方法,該方法聲明拋出了Checked異常,這表明該方法希望它的調(diào)用者來(lái)處理該異常。那么這段代碼要么放在try塊中顯示捕獲該異常,要么這段代碼處于另一個(gè)帶throws聲明拋出的方法中。
舉例如下:
//方法一:
import java.io.FileInputStream;
import java.io.IOException;
public class TestException2
{
// test() 方法拋出了異常,那么test()方法的調(diào)用者要么放在try塊中顯示捕獲該異常,要么這段代碼處于另一個(gè)帶throws聲明拋出的方法中。
// 以下為后者的處理方法
public static void test() throws IOException
{
FileInputStream fis = new FileInputStream("a.txt");
}
public static void main(String[] args) throws Exception
{
test();
}
}
//方法二:
import java.io.FileInputStream;
import java.io.IOException;
public class TestException2
{
public static void test() throws IOException
{
FileInputStream fis = new FileInputStream("a.txt");
}
public static void main(String[] args)
{
try
{
test();
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
使用throws聲明拋出異常時(shí)有一個(gè)限制:就是方法重寫(xiě)時(shí)的“兩小”中的一條規(guī)則:子類方法聲明拋出的異常類型應(yīng)該是父類方法聲明拋出的異常類型的子類或或相等,子類方法中不允許比父類方法聲明拋出更多異常。即如果子類拋出的異常是父類拋出的異常的父類,那么程序無(wú)法通過(guò)編譯。
因?yàn)镃hecked異常存在一些不便之處,大部分情況,可以使用Runtime異常,如果程序需要在合適的地方捕獲異常,并對(duì)異常進(jìn)行處理,程序一樣可以用try...catch捕獲Runtime異常。
使用throw拋出異常
當(dāng)程序出現(xiàn)錯(cuò)誤時(shí),系統(tǒng)會(huì)自動(dòng)拋出異常,另外,java也允許程序自行拋出異常,自行拋出異常使用throw語(yǔ)句完成!
拋出異常:
如果需要在程序中自行拋出異常,應(yīng)使用throw語(yǔ)句,throw語(yǔ)句可以單獨(dú)使用,throw語(yǔ)句拋出的不是異常類,而是一個(gè)異常實(shí)例,而且每次只能拋出一個(gè)異常實(shí)例。throw語(yǔ)句的格式如下:throw ExceptionInstance;
throw語(yǔ)句拋出異常的兩種情況:
1、當(dāng)throw語(yǔ)句拋出的異常是Checked異常,則該throw語(yǔ)句要么處于try塊里顯式捕獲該異常,要么放在一個(gè)帶throws聲明拋出的方法中,即把異常交給方法的調(diào)用者處理。
2、當(dāng)throw語(yǔ)句拋出的異常是Runtime異常,則該語(yǔ)句無(wú)須放在try塊內(nèi),也無(wú)須放在帶throws聲明拋出的方法中,程序既可以顯式使用try...catch來(lái)捕獲并處理該異常,也可以完全不理會(huì)該異常,把該異常交給方法的調(diào)用者處理。
舉例如下:
public class TestException3
{
public static void throwChecked(int a) throws Exception
{
if (a < 0)
{
throw new Exception("a的值大于0,不符合要求");
}
}
public static void throwRuntime(int a)
{
if (a < 0)
{
throw new RuntimeException("a的值大于0,不符合要求");
} else
{
System.out.println("a的值為:" + a);
}
}
public static void main(String[] args)
{
try
{
throwChecked(-3);
} catch (Exception e)
{
System.out.println(e.getMessage());
}
throwRuntime(3);
}
}
由上面的代碼顯式:自行拋出Runtime異常比自行拋出Checked異常的靈活性更好。
自定義異常類
用戶自定義異常都應(yīng)該繼承Exception基類,如果希望自定義Runtime異常,則應(yīng)該繼承RuntimeException基類。
應(yīng)以異常類通常需要提供兩種構(gòu)造器:一個(gè)是無(wú)參數(shù)的構(gòu)造器,另一個(gè)是帶一個(gè)字符串的構(gòu)造器,這個(gè)字符串將作為該異常對(duì)象的詳細(xì)說(shuō)明(也就是異常對(duì)象的getMessage方法的返回值)。
通常情況下,程序會(huì)很少自行拋出系統(tǒng)異常,因?yàn)楫惓5念惷ǔ0嗽摦惓5挠杏眯畔?,所以在選擇拋出什么異常時(shí),應(yīng)該選擇合適的異常類,從而可以明確地描述異常情況,這樣程序常常需要定義異常類。
用戶定義異常類,需要基礎(chǔ)Exception基類,如果希望定義RuntimeException基類,就應(yīng)該繼承該基類,定義異常類時(shí)通常需要提供兩種構(gòu)造器:
1、無(wú)參的構(gòu)造器。
2、帶字符串的構(gòu)造器,這個(gè)字符串作為該異常對(duì)象的詳細(xì)說(shuō)明,(也就是異常對(duì)象的getMessage方法返回值),調(diào)用super將字符串參數(shù)傳給異常對(duì)象的message屬性,message屬性就是異常對(duì)象的詳細(xì)描述信息。
例子如下:
public class TestException4 extends Exception
{
public TestException4()
{
}
public TestException4(String msg)
{
super(msg);
}
}
catch和throw同時(shí)使用
前面已有兩種異常處理方法:
1、在異常出現(xiàn)的方法內(nèi)捕獲并處理,方法的調(diào)用者將不能再次捕獲該異常。
2、該方法簽名中聲明拋出該異常,將該異常完全交給方法調(diào)用者處理。
但是在實(shí)際應(yīng)用中往往需要更復(fù)雜的處理方式,即異常出現(xiàn)的當(dāng)前方法中,程序只對(duì)異常進(jìn)行部分處理,還有些處理需要在該方法的調(diào)用者中才能完成,所以應(yīng)該再次拋出異常,可以讓該方法的調(diào)用者也能捕獲到異常。
為了實(shí)現(xiàn)這種靠多個(gè)方法協(xié)作處理同一個(gè)異常的情形,可以通過(guò)catch塊中結(jié)合throw來(lái)完成。
舉例catch和throw同時(shí)使用的例子:
public class TestException4
{
// 以下AuctionException這個(gè)異常是自定義的異常類
private double initPrice = 30.0;
public void bid(String bidPrice) throws AuctionException
{
double d = 0.0;
try
{
d = Double.parseDouble(bidPrice);
} catch (Exception e)
{
e.printStackTrace();
throw new AuctionException("競(jìng)拍價(jià)必須是數(shù)值,不能包含其他字符!");
}
if (initPrice > d)
{
throw new AuctionException("競(jìng)拍價(jià)比起拍價(jià)低,不允許競(jìng)拍!");
}
initPrice = d;
}
public static void main(String[] args)
{
TestException4 ta = new TestException4();
try
{
ta.bid("df");
} catch (AuctionException ae)
{
// TODO: handle exception
System.err.println(ae.getMessage());
}
}
}
catch和throw同時(shí)使用來(lái)處理異常的方法是在大型企業(yè)中比較常用的。
java的異常跟蹤棧
異常對(duì)象的printStackTrace方法用于打印異常的跟蹤棧信息,根據(jù)printStackTrace方法的輸出結(jié)果,我們可以找到異常的源頭,并跟蹤到異常一路觸發(fā)的過(guò)程。
雖然printStackTrace()方法可以很方便地追蹤異常的發(fā)生狀況,可以用它來(lái)調(diào)試,但是在最后發(fā)布的程序中,應(yīng)該避免使用它。而應(yīng)該對(duì)捕獲的異常進(jìn)行適當(dāng)?shù)奶幚?,而不是?jiǎn)單的將信息打印出來(lái)。
總之,要合理使用異常。
以上就是動(dòng)力節(jié)點(diǎn)java學(xué)院小編介紹的“java異常處理機(jī)制詳解”的內(nèi)容,希望對(duì)大家有幫助,如有疑問(wèn),請(qǐng)?jiān)诰€咨詢,有專業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)