一:Java的異常處理機制的優點:
1:把各種不同情況的異常情況分類,使用JAVA類來表示異常情況,這種類被稱為異常類。把各種異常情況表示成異常類,可以充分的發揮類的可擴展性和可重用性。
2:異常流程的代碼和正常流程的代碼分離,提高了代碼的可讀性,簡化了代碼的結構。
3:可以靈活的處理異常,如果發生了異常程序員可以手動拋出異常,也可以交給調用者來處理異常。
二:Java虛擬機的方法調用棧
Java虛擬機用方法來調用棧來跟蹤每個線程一系列的方法調用過程,該堆棧保存了每個調用方法的本地信息(比如說方法的局部變量)!每個線程都有一個獨立的方法調用棧。對於Java應用程序的主線程,堆棧的底部是程序的入口方法main();當一個新方法被調用的時候,java虛擬機把描述該方法的的棧置於棧頂,位於棧頂的方法即為正在執行的方法,方法調用順序,main()方法調用methodA()方法,而methodB()被methodA()方法調用!
如果方法中的代碼塊中出現了異常,可以使用以下兩種方式解決!
(1)在當前方法中使用try—catch結構捕獲到當前方法的異常!
1 public void methodA() 2 { 3 try{ 4 System.out.println(5/0); 5 }catch(ArimeticException e){ 6 7 //處理異常 8 } 9 }
(2)在方法聲明處通過throws語句拋出異常!
1 public void methodB thorws Exception() 2 { 3 System.out.println(5/0); 4 }
執行過程:當一個方法正常執行完畢的時候,java虛擬機會從棧中彈出該方法的棧結構,然后繼續處理前一個方法。如果在執行方法的過程中拋出了異常,則java虛擬機必須找出能捕獲該異常的catch代碼塊,它首先查看方法中是否存在這樣的代碼塊,如果存在則執行該代碼塊,否則Java虛擬機會從棧中彈出該方法的棧結構,繼續到前一個方法中找符合該異常的catch塊!
當java虛擬機執行到棧底的底部的方法時,如果仍然沒有找到處理該異常的的代碼塊,將按以下步驟處理:
(1):調用異常對象的printStackTrace()方法,打印來自方法調用棧的異常信息。
(2):如果該線程不是主線程,那么終止這個線程,其它線程繼續執行,如果該線程是主線程(即方法調用棧底部的main方法),那么整個應用程序會被終止
三:如何運用Java的異常處理機制
在java中一般使用try-catch語句來處理異常
try{ //可能出現異常的語句 }catch(Exception e){ //發生異常后執行的語句 }
public class Text{ public void MethodA(int money) throws Exception { if(money<0)thorw new Exception("錢數不符合規范") System.out.print("methodA"); } public void MethodB(int money) throws Exception { MethodA(money); System.out.print("methodB"); } public static void main(String[] args) { try{ new Text().method(-1); System.out.print("main"); }catch(Exception e){ System.out.print("wrong"); }
下面代碼輸出的正確結果Wrong。
finally語句:任何情況下都會執行的代碼(除非在catch塊中程序員手動停止程序的運行)
思考:為什么finally字句一定會被執行呢?
答案:編譯器確實是在每個catch語句塊后都添加了finally塊中的字節碼, try塊的最后也有int c = 300字節碼的冗余。如果翻譯成Java代碼應該這樣的:
1 public static void main(String[] args) { 2 try { 3 foo(); 4 int c = 300; // 冗余 5 } catch (IOException e) { 6 int a = 100; 7 8 int c = 300; // 冗余 9 } catch (Exception e) { 10 int b = 200; 11 int c = 300; // 冗余 12 } finally { 13 int c = 300; } }
詳見:http://blog.csdn.net/neosmith/article/details/48093427
異常語句的語法規則(try,catch,fianlly,throw,throws)
(1):try代碼塊不能脫離catch代碼塊或finally代碼塊單獨執行!
(2):try代碼塊后面可以有0個或多個catch塊,也可以由0個或多個finally塊,如果catch代碼塊和finally代碼塊共存,則必須保證fianlly代碼塊必須在catch塊之后!
(3):try代碼塊后可以只跟finally代碼塊!
(4):在try代碼塊中聲明的變量作用域僅限於try代碼塊,catch塊和fianlly塊無法訪問!
(5):當try代碼塊后跟着多個catch代碼塊時,java虛擬機會把實際拋出的異常對象依次和各個catch代碼塊中的異常類型進行匹配
(6):throw語句后不允許跟任何語句,因為這些語句永遠不會被執行(和return類似)
異常的處理原則:
(1):異常只能用於非正常情況(處理異常損耗性能)
(2):為異常有適當的說明
(3):保證異常的原子性(即發生異常后程序的各個部位都能回到運行初期正常的軌跡上(例:優化MySchool數據庫設計中的轉賬異常處理))
(4):避免龐大的try代碼塊(代碼越多,越容易引發異常)
(5):為catch塊准備好相應的異常類型(對症下葯,節約性能)