1、異常處理機制:Java中定義了很多異常類,每個異常類都代表一種運行錯誤,類中包含了該運行錯誤的信息和處理錯誤的方法等內容。每當Java程序運行過程中發生一個可識別的運行錯誤時,即該錯誤有一個異常類與之對應時,系統都會產生一個相應的該異常的對象,即產生一個異常。一旦異常對象產生,系統就一定有相應的機制來處理它,確保不會產生死機、死循環或其他對OS的損害,從而保證程序運行的安全性。
2、異常的類層次:Throwable類是所有異常和錯誤類的最上層,此類派生了兩個子類:Exception類和Error類。Exception類是所有異常類的父類,Error類是所有錯誤類的父類,前者供程序使用,后者由系統保留。所有的異常類都分布在:java.lang、java.io、java.util、java.net包中。
3、異常的處理:Java異常處理通過5個關鍵字控制:try、catch、throw、throws和finally
4、try-catch-finally結構
語法格式:
try{ //try語句塊
需要檢查的語句;//拋出具體的異常代碼
}
cathc(異常類名1 變量名)//catch語句塊
{
異常類發生時的處理語句;
……
}
……
catch(異常類名n 變量名)//catch語句塊
{
異常類發生時的處理語句;
……
}
finally //finally語句塊
{
必須要執行的語句;
}
注:try用來捕獲異常,catch用來處理相應異常,finally用以進行異常清理。
5、throw語句——產生異常
實例:
public class Test
{
static void throwDemo()
{
try
{
throw new NullPointerException("demo");
}
catch (NullPointerException e)
{
System.out.println("Caught inside demoproc.");
throw e;//重新拋出異常
}
}
public static void main(String args[])
{
//main方法捕捉并處理throwDemo拋出的異常
try
{
throwDemo();
}
catch (NullPointerException e)
{
e.printStackTrace();
}
}
}
6、throws語句:如一個定義的方法中存在異常,可在方法聲明的后面加上throws關鍵字將異常拋出到此方法的調用方法中。
例子:
public class Test
{
static void throwDemo() throws NullPointerException
{
System.out.println("Caught inside demoproc.");
throw new NullPointerException("demo");
}
public static void main(String args[])
{
//main方法捕捉并處理throwDemo拋出的異常
try
{
throwDemo();
}
catch (NullPointerException e)
{
e.printStackTrace();
}
}
}
7、自定義異常類:某個應用程序所特有的運行錯誤,需要開發人員根據實際情況創建自己的異常類。自定義的異常類必須是Throwable類的直接或間接子類,實際應用中,通常以Exception類作為其直接父類。在異常類中定義其屬性和方法,或者重載父類的屬性和方法。
例子:
public class Test
{
static void student(double score)throws MyException
{
if(score>100)
throw new MyException(score);
System.out.println("此學生的成績是:"+score);
}
public static void main(String args[])
{
try
{
student(80.5);
student(100.5);
}
catch (MyException e)
{
//System.out.println(e);
//printStackTrace()的輸出包含錯誤信息和軌跡
e.printStackTrace();
}
}
}
class MyException extends Exception
{
//學生成績>100的異常
private double score;
MyException(double score)
{
this.score=score;
}
public String toString()
{
return "你輸入了>100的成績:"+score;
}
}
8、斷言(assertion):
在軟件開發中,斷言是一種經典的調試和測試方式。Java1.4中新添加了斷言的功能,是Java中的一種新的錯誤檢查機制,提供了一種在代碼中進行正確檢查的機制。在編譯或運行Java程序時,可通過相應的參數來打開或關閉斷言功能。在實現中,assertion就是在程序中的一條語句,對一個boolean表達式進行檢查,程序正確將為ture,否則為false,此時系統將給出警告或退出。
斷言包括:assert關鍵字,assertionerror類,以及在java.lang.classloader中幾個新的有關斷言的方法。一般來說,assertion用于保證程序最基本、關鍵的正確性。
斷言有兩種合法的形式:
§assert expression1;
§assert expression1:expression2;
expression1表示一個布爾表達式,expression2表示一個基本類型或者一個對象,基本類型包括boolan、char、double、float、int和long,由于所有類都是Object的子類,因而可以處理一切對象。運行時,如打開斷言功能,expresson1將被計算,若計算的值為flase,此語句將拋出一個AssertionError對象。如果assertion語句包括expression2,程序將計算出expression2的結果,然后將這個結果作為AssertionError的構造函數的參數,來創建AssertionError對象,并拋出此對象。若計算的值為true,expresson2將不被計算。如果在計算表達式時,表達式本身拋出異常,那么assert將停止運行,而拋出這個異常。
斷言程序的編譯:必須使用JDK1.4及比其更新版本,在使用javac命令時,必須加上-source 1.4,一個簡單的例子:javac -source 1.4 Test.java
斷言的使用是一個復雜的問題,將涉及程序的風格、斷言運用的目標、程序的性質等。通常來說,用來檢查一些關鍵值,這些值對整個程序或者局部功能的完成有很大的影響,這種錯誤是不容易恢復的。
§檢查控制流:在if-then和switch-case語句中,可以在不該被執行的控制流之上,加assert false語句。
例子:程序只能取1、2、3。
switch(x)
{
case 1:。。;
case 2:。。;
case 3:。。;
default:assert false:"x value is invalid:"+x;
}
§在私有函數計算前,檢查輸入參數是否有效。對一地一些私有函數,要求輸入滿足一些特定的條件,可在函數開始處使用asser進行參數檢查。對于公共函數,通常不用,因為一般來說,公共函數必須對無效的參數進行檢查和處理,而私有函數是直接使用的。如某函數要求輸入的參數必須不為null,可以在函數開始加上斷言:assert parameter1!null:"paramerter is null in test metod";
§在函數計算后,檢查函數結果是否有效。對于一些計算函數,運行完成后,某些值需要保證一定的性質,如有一個計算絕對值的函數:assert value>=0:"value should be bigger than 0:"+value;
§檢查不變量,有些程序中存在一些不變量,在程序的運行生命周期,這些變量的值都是不變的。這些不變量可能是一簡單的表達式,也可能是一個復雜的表達式。對于一些關鍵的不變量,可以通過assert進行檢查。如在一個財會系統中,公司的支出和收入必須保持一定的平衡關系,編寫一個表達式檢查平衡關系。
private boolean isBalance()
{
............
}
在這個系統中,在一些可能影響這種平衡關系的方法前后,都可以加上斷言驗證:
assert isBalnace():"balance is destoried";