java通过异常处理错误,java基础之通过错误处理异常
我們?cè)诰幊踢^(guò)程中,通常需要時(shí)刻關(guān)注可能遇到的問(wèn)題,此時(shí)可以把問(wèn)題分為兩類:普通問(wèn)題與異常問(wèn)題。普通問(wèn)題:我們可以通過(guò)從當(dāng)前環(huán)境中獲取到的信息來(lái)解決這個(gè)問(wèn)題;而異常問(wèn)題:在當(dāng)前環(huán)境中獲取到的信息并不能解決這個(gè)問(wèn)題,所以我們阻止了程序的執(zhí)行,跳出當(dāng)前的環(huán)境,將這個(gè)異常問(wèn)題,拋到上一級(jí)的環(huán)境中去解決。可以看出異常機(jī)制存在兩種基本模型:終止模型(假設(shè)異常非常的關(guān)鍵,程序無(wú)法自我修復(fù))和恢復(fù)模型(可以通過(guò)異常處理程序,調(diào)用相應(yīng)的方法來(lái)修復(fù)出現(xiàn)的錯(cuò)誤),然而我們現(xiàn)在所見(jiàn)到的基本為終止模型。
如果方法內(nèi)部出現(xiàn)了異常,方法將在拋出異常的過(guò)程中終止。我們可以通過(guò)try建立監(jiān)控區(qū),在出現(xiàn)異常時(shí)跳轉(zhuǎn)到catch區(qū)讓方法繼續(xù)執(zhí)行。我們?cè)诰幊踢^(guò)程中,關(guān)注的重點(diǎn)常在于異常的名字,所以我們可以定義自己需要的異常,此時(shí)只需要繼承Exception類即可,例如:
public class LogingException extends Exception{
private static final long serialVersionUID = 1L;
private static Logger logger = Logger.getLogger("LoggingException");
public LogingException(){
StringWriter trace = new StringWriter();
printStackTrace(new PrintWriter(trace));
logger.severe(trace.toString());
}
}
我們實(shí)現(xiàn)在一個(gè)異常,同時(shí)重載了printStackTrace()方法,增加了一個(gè)新的功能,在拋出異常時(shí)可以自動(dòng)記錄日志。printStackTrace()方法會(huì)打印Throwable和Throwable的調(diào)用棧軌跡,我們可以通過(guò)getStackTrace()獲取printStackTrace()所提供的信息,會(huì)返回一個(gè)由棧軌跡中的元素所構(gòu)成的數(shù)組,元素0為棧頂元素,為調(diào)用序列中的最后一個(gè)方法的調(diào)用;最后一個(gè)元素為棧底元素,為調(diào)用序列中的第一個(gè)方法的調(diào)用。我們也可以在catch中將異常重新拋出,此時(shí)printStackTrace()顯示的為原來(lái)的異常拋出點(diǎn)的調(diào)用棧信息,如果想顯示重新拋出點(diǎn)的信息,可以先調(diào)用fillInStackTrace()方法,但此時(shí)原來(lái)異常拋出點(diǎn)的調(diào)用棧信息會(huì)丟失。
如果我們也需要顯示原始異常的信息該怎么做呢?Throwable的構(gòu)造方法中其中一個(gè)就是介紹cause對(duì)象作為參數(shù),cause表示原始異常,可以將原始異常傳遞給新的異常。在出現(xiàn)異常時(shí),可以通過(guò)這樣的異常鏈追蹤到異常的最初位置,這也是為什么我們調(diào)試異常時(shí)先從最下面開(kāi)始看起。
如果我們?cè)诜椒ㄖ袙伋霎惓r(shí),Java強(qiáng)制我們禮貌的告訴別人某個(gè)方法可能會(huì)拋出的異常類型,這樣別人在調(diào)用這個(gè)方法時(shí)就可以作相應(yīng)的處理,這就是異常說(shuō)明,通過(guò)關(guān)鍵字throws來(lái)實(shí)現(xiàn),它屬于方法聲明的一部分。在Java的繼承關(guān)系中關(guān)于異常由以下幾個(gè)需要注意的點(diǎn):
①如果父類某個(gè)非構(gòu)造方法拋出了異常,那么子類相應(yīng)的方法只能拋出基類方法中列出的那些異常或異常派生出的異常。
②對(duì)于構(gòu)造方法則恰恰相反,子類構(gòu)造方法必須拋出包含父類構(gòu)造方法所拋出的異常,這是由于子類通常需要調(diào)用父類的構(gòu)造方法進(jìn)行初始化。
③雖然編譯器對(duì)異常說(shuō)明做了強(qiáng)制要求,但是異常說(shuō)明并不屬于方法類型一部分,所以就不要想著能通過(guò)拋出不同的異常來(lái)重載方法了。
④在catch方法對(duì)異常類型進(jìn)行匹配時(shí),catch中的參數(shù)exception會(huì)匹配該異常類及其子類,匹配成功后,java會(huì)認(rèn)為異常得到了處理,就不在繼續(xù)向下查找了,這點(diǎn)和以前所學(xué)的switch不同,沒(méi)有break之類的。這點(diǎn)非常重要,如果你修改程序方法,拋出了跟具體派生異常,別人并不需修改代碼也可以捕獲該異常。例如:
class Annoyance extends Exception{};
class Sneeze extends Annoyance{};
public class Human {
public static void main(String[] args) {
try{
throw new Annoyance();
}catch(Sneeze s){
System.out.println("Caught Sneeze");
}catch(Annoyance a){
System.out.println("Caught Annoyance");
}
try{
throw new Sneeze();
}catch(Annoyance a){
System.out.println("Caught Annoyance");
}
//catch(Sneeze s){
//System.out.println("Caught Sneeze");
//}
}
}
java中還存在一類比較特殊的異常RuntimeException(常見(jiàn)到的NullPointerException就屬于它),這屬于運(yùn)行時(shí)異常,編譯器不對(duì)異常聲明進(jìn)行強(qiáng)制檢查。這也能給我?guī)?lái)很多的便利,我們可以不用寫try/catch或異常聲明,如果出現(xiàn)異常,會(huì)自動(dòng)沿著調(diào)用棧向上冒泡。也可以通過(guò)前面提到的異常鏈,使用RuntimeException包裝強(qiáng)制檢查的異常,然后通過(guò)getCause()捕獲特定的異常。
總結(jié)
以上是生活随笔為你收集整理的java通过异常处理错误,java基础之通过错误处理异常的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: oracle 备份
- 下一篇: 遮罩,在指定元素上进行遮罩