Java中的異常處理機制的簡單原理和應用:
異常是指java程式運行時(非編譯)所發生的非正常情況或錯誤,與現實生活中的事件很相似,現實生活中的事件可以包含事件發生的時間、地點、人物、情節等資訊,可以用一個對象來表示,Java使用物件導向的方式來處理異常,它把程式中發生的每個異常也都分別封裝到一個對象來表示的,該對象中包含有異常的資訊。
Java對異常進行了分類,不同類型的異常分別用不同的Java類表示,所有異常的根類為java.lang.Throwable,Throwable下面又派生了兩個子類:Error和Exception,Error 表示應用程式本身無法克服和恢複的一種嚴重問題,程式只有死的份了,例如,說記憶體溢出和線程死結等系統問題。Exception表示程式還能夠克服和恢複的問題,其中又分為系統異常和普通異常,系統異常是軟體本身缺陷所導致的問題,也就是軟體開發人員考慮不周所導致的問題,軟體使用者無法克服和恢複這種問題,但在這種問題下還可以讓軟體系統繼續運行或者讓軟體死掉,例如,數組指令碼越界(ArrayIndexOutOfBoundsException),null 指標異常(NullPointerException)、類轉換異常(ClassCastException);普通異常是運行環境的變化或異常所導致的問題,是使用者能夠克服的問題,例如,網路斷線,硬碟空間不夠,發生這樣的異常後,程式不應該死掉。
java為系統異常和普通異常提供了不同的解決方案,編譯器強制普通異常必須try..catch處理或用throws聲明繼續拋給上層調用方法處理,所以普通異常也稱為checked異常,而系統異常可以處理也可以不處理,所以,編譯器不強制用try..catch處理或用throws聲明,所以系統異常也稱為unchecked異常。
首先看一下異常的體系:
Throwable:
Error :通常出現重大問題如:啟動並執行類不存在或者記憶體溢出等。
不編寫針對代碼對其處理
Exception: 在運行時運行出現的一起情況,可以通過try{} catch(){} finally{}
Exception和Error的子類名都是以父類名作為尾碼。
如RuntimeException
Trowable中的一些常用方法:
getMessage() 擷取異常資訊,返回字串。
toString() 擷取異常類和異常資訊
printStackTrace()擷取異常類名和異常資訊,以及異常出現在程式中的位置。傳回值void
printStackTrace(PrintStream s)
通常用該方法將異常內容儲存在記錄檔中,以便查閱
異常處理的具體格式:
try
{
需要檢測的代碼;
}
catch(異常類變數)
{
異常處理代碼;
}
finally
{
一定會執行的代碼;
}
注意:Finally代碼塊只有一種情況不會被執行。就是在之前執行了System.exit(0)。
方法中的其他代碼
如果代碼正確,那麼程式不經過catch語句直接向下運行;
如果代碼不正確,則將返回的異常對象和e進行匹配,如果匹配成功,則處理其後面的異常處理代碼。
try中如果發現錯誤,即跳出try塊去匹配catch,那麼try後面的語句就不會被執行。
一個try可以跟多個catch語句,用於處理不同情況,但是不能將父類型的exception的位置寫在子類型的excepiton之前。
在try-catch後還可以再跟一子句finally。其中的代碼語句論有沒有異常都會被執行(因為finally子句的這個特性,所以一般將釋放資源,關閉串連的語句寫在裡面)。
finally中的代碼和try-catch中的代碼衝突時,finally中的代碼一定會被執行且會忽略try-catch中的代碼。但是如果try-catch中有System.exit(0);(虛擬機器退出語句),則不會去執行fianlly中的代碼。
throws/throw處理方式:
throw 寫在方法內,後面跟一個異常對象。
throws 在方法的定義中說明方法可能拋出的異常,後面跟異常類的名字,聲明這個方法將不處理異常,把異常交給上一級方法處理。
調用時,調用者不能拋出範圍更小的異常。
對於方法a,如果它定義了throws Exception。那麼當它調用的方法b返回異常對象時,方法a並不處理,而將這個異常對象向上一級返回,如果所有的方法均不進行處理,返回到主方法,如主方法也不進行處理,則到虛擬機器中,程式中止。
如果在方法的程式中有一行throw new Exception(),那麼其後的程式不執行,如果沒有對這個可能出現的檢查結果進行處理,那麼程式就會報錯。
throws和throw沒有必然的聯絡。
注意:
方法的覆蓋中,如果子類的方法拋出的例外是父類方法拋出的例外的父類型,那麼編譯就會出錯:子類無法覆蓋父類。
子類拋出的例外或者與父類拋出的例外一致,或者是父類拋出例外的子類型,或者子類型不拋出例外。
如果父類型無throws時,子類型也不允許出現throws。此時只能使用try catch。
自訂異常:
a. 使其繼承Exception或者RuntimeException。
b. 寫構造器,直接調用父類的構造器
斷言(assert):用來調試、測試代碼
throw和throw關鍵字的區別:
throws用在函數上,後面跟異常的類名,可以追加多個異常類名,用逗號分開
throw 用於函數內, 後面跟異常的對象。
異常處理的幾個格式:
第一個格式:
try
{
}
catch ()
{
}
第二個格式:
try
{
}
catch ()
{
}
finally
{
}
第三個格式:
try
{
}
finally
{
}
註:catch是用於處理異常。如果沒有catch就代表異常沒有被處理過,如果該異常是檢測時異常。那麼必須聲明。
自訂異常:
如下://自訂異常,用於處理除數為負數的情況:
*/
class FuShuException extends Exception //getMessage();
{
private int value;
FuShuException()
{
super();
}
FuShuException(String msg,int value)
{
super(msg);
this.value = value;
}
public int getValue()
{
return value;
}
}
class Demo
{
int div(int a,int b)throws FuShuException
{
if(b<0)
throw new FuShuException("出現了除數是負數的情況------ / by fushu",b);//手動通過throw關鍵字拋出一個自訂異常對象。
return a/b;
}
}
class ExceptionDemo3
{
public static void main(String[] args)
{
Demo d = new Demo();
try
{
int x = d.div(4,-9);
System.out.println("x="+x);
}
catch (FuShuException e)
{
System.out.println(e.toString());
//System.out.println("除數出現負數了");
System.out.println("錯誤的負數是:"+e.getValue());
}
System.out.println("over");
}
}
/*
class Throwable
{
private String message;
Throwable(String message)
{
this.message = message;
}
public String getMessage()
{
return message;
}
}
使用異常要注意的一些細節:
1.RuntimeException以及其子類如果在函數中被throw拋出,可以不用在函數上聲明。
如ArithmeticException,可以通過代碼上的處理避免
2.自訂異常時,如果該異常的發生,無法再繼續計算,可以讓自訂的異常繼承RuntimException
3.如果父類拋出多個異常,那麼重寫(覆蓋)方法必須拋出那些異常 的一個子集,不能拋出新的異常。
包與包之間進行訪問的總結:
包與包之間進行訪問,被訪問的包中的類以及類中的成員,需要public修飾。
不同包中的子類還可以直接存取父類中被protected許可權修飾的成員。
包與包之間可以使用的許可權只有兩種,public protected。
public protected default private
同一個類中 ok ok ok ok
同一個包中 ok ok ok
子類 ok ok
不同包中 ok
java.lang : java的核心包 jdk1.2版本以後,該包中的類自動匯入。
java.awt: 用於製作圖形介面。
java.io:input output 用於操作裝置上的資料。
java.util : 這裡定義是java的工具類。集合,日期。
java.net:用於網路通訊的。