更新時間:2019-08-28 11:37:03 來源:動力節(jié)點 瀏覽2491次
動力節(jié)點java學院小編介紹的“java異常處理機制詳解”的內(nèi)容太長,上文鏈接請看:http://www.dabaquan.cn/javazixun/1654.html
Checked異常和Runtime異常體系
java異常被分為兩大類:Checked異常和Runtime異常(運行時異常)。
所有RuntimeException類及其子類的實例被稱為Runtime異常,不是RuntimeException類及其子類的異常實例則被稱為Checked異常。
只有java語言提供了Checked異常,其他語言都沒有提供,java認為Checked異常都是可以被處理(修復)的異常,所以java程序無須顯式的處理Checked異常。如果程序沒有處理Checked異常,該程序在編譯時就會發(fā)生錯誤,無法通過編譯。
Checked異常的處理方式:
(1)當方法明確知道如何處理異常,程序應該使用try...catch塊來捕獲該異常,然后在對應的catch塊中修補該異常。
(2)當方法不知道如何處理異常,應該在定義該方法時聲明拋出該異常。
Runtime異常無須顯式聲明拋出,如果程序需要捕捉Runtime異常,也可以使用try...catch塊來捕獲Runtime異常。
問題是:大部分的方法總是不能明確知道如何處理異常,這就只能聲明拋出異常了。
使用throws拋出異常
使用throws拋出異常的思路是:當前方法不知道如何處理這種類型的異常,該異常應該由上一級調(diào)用者處理,如果main方法也不知道應該如何處理這種類型的異常,也可以使用使用throws聲明拋出異常,該異常將交給JVM來處理。
JVM對異常的處理方法:打印異常跟蹤棧的信息,并終止程序運行,所以有很多程序遇到異常后自動結束。
使用throws拋出異常的格式:
throws聲明的拋出的語法格式緊跟在方法之后,可以聲明多個異常類,多個異常類之間以逗號隔開。一旦使用了throws語句聲明拋出異常,就不用再使用try...catch來捕獲異常了。
如:throws ExceptionClass1,ExceptionClass2...
注意點1:如果某段代碼調(diào)用了一個帶throws聲明的方法,該方法聲明拋出了Checked異常,這表明該方法希望它的調(diào)用者來處理該異常。那么這段代碼要么放在try塊中顯示捕獲該異常,要么這段代碼處于另一個帶throws聲明拋出的方法中。
舉例如下:
//方法一:
import java.io.FileInputStream;
import java.io.IOException;
public class TestException2
{
// test() 方法拋出了異常,那么test()方法的調(diào)用者要么放在try塊中顯示捕獲該異常,要么這段代碼處于另一個帶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聲明拋出異常時有一個限制:就是方法重寫時的“兩小”中的一條規(guī)則:子類方法聲明拋出的異常類型應該是父類方法聲明拋出的異常類型的子類或或相等,子類方法中不允許比父類方法聲明拋出更多異常。即如果子類拋出的異常是父類拋出的異常的父類,那么程序無法通過編譯。
因為Checked異常存在一些不便之處,大部分情況,可以使用Runtime異常,如果程序需要在合適的地方捕獲異常,并對異常進行處理,程序一樣可以用try...catch捕獲Runtime異常。
使用throw拋出異常
當程序出現(xiàn)錯誤時,系統(tǒng)會自動拋出異常,另外,java也允許程序自行拋出異常,自行拋出異常使用throw語句完成!
拋出異常:
如果需要在程序中自行拋出異常,應使用throw語句,throw語句可以單獨使用,throw語句拋出的不是異常類,而是一個異常實例,而且每次只能拋出一個異常實例。throw語句的格式如下:throw ExceptionInstance;
throw語句拋出異常的兩種情況:
1、當throw語句拋出的異常是Checked異常,則該throw語句要么處于try塊里顯式捕獲該異常,要么放在一個帶throws聲明拋出的方法中,即把異常交給方法的調(diào)用者處理。
2、當throw語句拋出的異常是Runtime異常,則該語句無須放在try塊內(nèi),也無須放在帶throws聲明拋出的方法中,程序既可以顯式使用try...catch來捕獲并處理該異常,也可以完全不理會該異常,把該異常交給方法的調(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異常的靈活性更好。
自定義異常類
用戶自定義異常都應該繼承Exception基類,如果希望自定義Runtime異常,則應該繼承RuntimeException基類。
應以異常類通常需要提供兩種構造器:一個是無參數(shù)的構造器,另一個是帶一個字符串的構造器,這個字符串將作為該異常對象的詳細說明(也就是異常對象的getMessage方法的返回值)。
通常情況下,程序會很少自行拋出系統(tǒng)異常,因為異常的類名通常包含了該異常的有用信息,所以在選擇拋出什么異常時,應該選擇合適的異常類,從而可以明確地描述異常情況,這樣程序常常需要定義異常類。
用戶定義異常類,需要基礎Exception基類,如果希望定義RuntimeException基類,就應該繼承該基類,定義異常類時通常需要提供兩種構造器:
1、無參的構造器。
2、帶字符串的構造器,這個字符串作為該異常對象的詳細說明,(也就是異常對象的getMessage方法返回值),調(diào)用super將字符串參數(shù)傳給異常對象的message屬性,message屬性就是異常對象的詳細描述信息。
例子如下:
public class TestException4 extends Exception
{
public TestException4()
{
}
public TestException4(String msg)
{
super(msg);
}
}
catch和throw同時使用
前面已有兩種異常處理方法:
1、在異常出現(xiàn)的方法內(nèi)捕獲并處理,方法的調(diào)用者將不能再次捕獲該異常。
2、該方法簽名中聲明拋出該異常,將該異常完全交給方法調(diào)用者處理。
但是在實際應用中往往需要更復雜的處理方式,即異常出現(xiàn)的當前方法中,程序只對異常進行部分處理,還有些處理需要在該方法的調(diào)用者中才能完成,所以應該再次拋出異常,可以讓該方法的調(diào)用者也能捕獲到異常。
為了實現(xiàn)這種靠多個方法協(xié)作處理同一個異常的情形,可以通過catch塊中結合throw來完成。
舉例catch和throw同時使用的例子:
public class TestException4
{
// 以下AuctionException這個異常是自定義的異常類
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("競拍價必須是數(shù)值,不能包含其他字符!");
}
if (initPrice > d)
{
throw new AuctionException("競拍價比起拍價低,不允許競拍!");
}
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同時使用來處理異常的方法是在大型企業(yè)中比較常用的。
java的異常跟蹤棧
異常對象的printStackTrace方法用于打印異常的跟蹤棧信息,根據(jù)printStackTrace方法的輸出結果,我們可以找到異常的源頭,并跟蹤到異常一路觸發(fā)的過程。
雖然printStackTrace()方法可以很方便地追蹤異常的發(fā)生狀況,可以用它來調(diào)試,但是在最后發(fā)布的程序中,應該避免使用它。而應該對捕獲的異常進行適當?shù)奶幚恚皇呛唵蔚膶⑿畔⒋蛴〕鰜怼?/p>
總之,要合理使用異常。
以上就是動力節(jié)點java學院小編介紹的“java異常處理機制詳解”的內(nèi)容,希望對大家有幫助,如有疑問,請在線咨詢,有專業(yè)老師隨時為你服務。
0基礎 0學費 15天面授
有基礎 直達就業(yè)
業(yè)余時間 高薪轉行
工作1~3年,加薪神器
工作3~5年,晉升架構
提交申請后,顧問老師會電話與您溝通安排學習