摘要:總結(jié)異??偟膩碚f還是很重要的,也是保障程序健壯性很重要的一欄,并且可以達(dá)到立竿見影的效果,這里只是基本總結(jié)了異常的一些常見問題,很多還得在自己運(yùn)用的過程中去探索。
概述
說起異常,我就想起了Bug,也就是常說的信春哥,無Bug,什么是Bug呢?我理解的Bug就是沒有按照自己原先假想的邏輯去執(zhí)行,這其中包括了兩個(gè)方面,一方面是代碼語(yǔ)法問題,一方面是邏輯問題,就比如正常邏輯買了東西要付款,但是買家買了東西卻沒有付款,直接拿東西走了,這是邏輯問題,或者是本來數(shù)組存儲(chǔ)3個(gè)元素,你卻存了4個(gè),這時(shí)候也出現(xiàn)了Bug,程序報(bào)錯(cuò)了,這種Bug就是異常。
異常也是Java類的一種,用new創(chuàng)建對(duì)象,他們的結(jié)構(gòu)是這樣的:
Throwable
error
Exception
恩,就是這樣,異常分為錯(cuò)誤和異常,感覺有點(diǎn)繞口,但就是這樣,像error這種錯(cuò)誤是在編譯期間就會(huì)報(bào)出來的,如果你使用的是IDE,所以我們只需要關(guān)注Exception異常就可以了。
獲取異常和處理異常獲取和處理異??赡芫褪钱惓5娜浚覀兊囊粋€(gè)原則就是:
發(fā)生異常就得讓程序員知道
獲取異常怎么獲取異常呢?Java給出了try關(guān)鍵字用來解決,我們只需要將可能出現(xiàn)異常的代碼放在try中就可以了,就像這樣:
try{ ... }
java給出了盡量?jī)?yōu)雅的解決方案來處理異常,它不希望處理異常的代碼和本身的業(yè)務(wù)代碼有過多的混合,獲取到異常就該處理異常,這時(shí)候就應(yīng)該這樣寫了:
try{ ... }catch(Type1 type1){ ... }catch(Type2 type2){ ... }
catch中的type代表了在try中可能出現(xiàn)的異常類型
catch如何匹配異常?
按順序從第一個(gè)到最后一個(gè),如果發(fā)現(xiàn)異常匹配,就停止匹配,和switch模式不一樣
基類包含子類異常,如果第一個(gè)是Exception,那么后面的都不用匹配了
那么catch中怎么處理這個(gè)異常呢?
不作處理(會(huì)出現(xiàn)“吞食”)
打印到控制臺(tái)
寫入日志
繼續(xù)向上拋
在try塊中拋出異常,我們?cè)赾atch中會(huì)匹配到相應(yīng)的異常類型,這時(shí)候我們就會(huì)拿到對(duì)應(yīng)的異常對(duì)象的引用,我們調(diào)用throwalbe的方法用于處理:
public class ExceptionMethods { public static void main(String[] args) { try { throw new Exception("My Exception"); } catch (Exception e) { System.out.println("Caught Exception"); System.out.println(e.getMessage()); System.out.println(e.getLocalizedMessage()); System.out.println(e); System.out.println(e.toString()); e.printStackTrace(); e.printStackTrace(System.out); } } }
我們一般使用e.printStackTrace();打出異常棧信息即可
或者是寫入Log,使用logger.error
每個(gè)人處理處理異常的方式可能不盡相同
我們除了可以使用try來捕獲異常,我們也可以將這個(gè)異常拋出去,我們可以把異常比作現(xiàn)在這種制度,地球村出了點(diǎn)問題,村長(zhǎng)衡量了一下,覺得這事情自己處理不了,就交給鄉(xiāng)長(zhǎng)了,這種把問題交給上層或者是Java編程思想中說的跳出當(dāng)前環(huán)境,交給一個(gè)更大的環(huán)境去處理,這也是Java異常處理的一種思路。
if(t == null) throw new NullPointerException();
其實(shí)異常最重要的就是異常的名稱,現(xiàn)在Java正在擴(kuò)充異常的種類,但是很多異常可能不是我們想要的,那么我們就可以自定義異常:
class SystemErrException extends Exception{ }
這就是一個(gè)異常類,我們繼承了Exception,這個(gè)SysteErrException就可以用于我們處理異常的時(shí)候了,當(dāng)然我們可以給他加點(diǎn)參數(shù):
class SystemErrException extends Exception{ public SystemErrException(){ } public SystemErrException (String message){ super(message); } }
或者是這樣:
class SystemErrException extends Exception{ private int i; public SystemErrException(){ } public SystemErrException (String message){ super(message); } public SystemErrException (String message, int i){ super(message); this.i = i; } }
這只不過是多加了幾個(gè)參數(shù),但是這些一般是沒什么必要的。
throws說到這,就得說另一個(gè)關(guān)鍵字throws,看清楚,不是throw,而是throws,這可能也是面試新手的時(shí)候會(huì)問的一個(gè)問題,throws是異常中的一個(gè)申明,在IO學(xué)習(xí)中會(huì)非常常見,它是一個(gè)聲明,編譯器檢查到說你這段代碼可能會(huì)發(fā)生什么異常,你要聲明一下,這時(shí)候你就要在方法上聲明:
public void inputFile() throws IOException{ .... }finally
finally用處就和他的意思相符,表示最終的含義,也就是finally里面的代碼一定會(huì)得到執(zhí)行:
案例一
public class FinallyException { static int count = 0; public static void main(String[] args) { while (true){ try { if (count++ == 0){ throw new ThreeException(); } System.out.println("no Exception"); }catch (ThreeException e){ System.out.println("ThreeException"); }finally { System.out.println("in finally cause"); if(count == 2) break; } } } } class ThreeException extends Exception{ }
執(zhí)行結(jié)果:
ThreeException in finally cause no Exception in finally cause
案例二:return案例
public class MultipleReturns { public static void f(int i){ System.out.println("start......."); try { System.out.println("1"); if(i == 1) return; System.out.println("2"); if (i == 2) return; System.out.println("3"); if(i == 3) return; System.out.println("else"); return; }finally { System.out.println("end"); } } public static void main(String[] args) { for (int i = 1; i<4; i++){ f(i); } } }
執(zhí)行結(jié)果:
start....... 1 end start....... 1 2 end start....... 1 2 3 end最佳實(shí)踐
我們可能遇到這種情況,打開一個(gè)文件,讀取文件,關(guān)閉文件,正常邏輯是這樣的,但是這樣會(huì)有幾個(gè)問題:
在打開文件的過程中出現(xiàn)異常,但是還要關(guān)閉文件
就像這樣:
try{ A a = new A(); ... }catch(){ ... }finally{ a.close(); }
A在創(chuàng)建過程中會(huì)出現(xiàn)異常,但是還是會(huì)執(zhí)行a的方法,比如關(guān)閉文件
所以我們應(yīng)該這么做:
try{ A a = new A(); try{ ... }finally{ a.close(); } }catch(){ ... }異常棧
一般報(bào)錯(cuò)都會(huì)報(bào)一大堆錯(cuò)誤,大家無從看起,其實(shí)異常報(bào)錯(cuò)也是有規(guī)律的,這就是棧結(jié)構(gòu),先進(jìn)后出,舉個(gè)栗子:
public class WhoCalled { static void f() { try { throw new Exception(); } catch (Exception e) { for (StackTraceElement ste : e.getStackTrace()){ System.out.println(ste.getMethodName()); } } } static void g(){ f(); } static void h(){ g(); } public static void main(String[] args) { f(); System.out.println("---------------------------"); g(); System.out.println("---------------------------"); h(); System.out.println("---------------------------"); } }
運(yùn)行結(jié)果:
f main --------------------------- f g main --------------------------- f g h main ---------------------------
可以看到異常信息都是從內(nèi)到外的,按我的理解查看異常的時(shí)候要從第一條異常信息看起,因?yàn)槟鞘钱惓0l(fā)生的源頭。
總結(jié)異??偟膩碚f還是很重要的,也是保障程序健壯性很重要的一欄,并且可以達(dá)到立竿見影的效果,這里只是基本總結(jié)了異常的一些常見問題,很多還得在自己運(yùn)用的過程中去探索。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/65147.html
摘要:前言編程思想這本書,陸陸續(xù)續(xù)讀了年,終于基本都瀏覽了一遍。每個(gè)對(duì)象對(duì)外暴露接口,程序通過對(duì)象暴露的接口向?qū)ο蟀l(fā)送消息,獲取該對(duì)象的服務(wù)能力。異常處理異常處理,為編寫程序階段提供了一種預(yù)見性的防止程序崩潰的出路。 前言 《Java編程思想》這本書,陸陸續(xù)續(xù)讀了1年,終于基本都瀏覽了一遍。通過這本書,試圖理解作者的想法,才真的體會(huì)到Java思想。感謝本書的作者,不僅講述了java的語(yǔ)法,更...
摘要:系列博文目錄編程思想學(xué)習(xí)錄連載之一切都是對(duì)象編程思想學(xué)習(xí)錄連載之初始化與清理編程思想學(xué)習(xí)錄連載之內(nèi)部類編程思想學(xué)習(xí)錄連載之異常本篇文章將講述關(guān)于異常的相關(guān)知識(shí)注本文首發(fā)于公眾號(hào),可長(zhǎng)按或掃描下面的小心心來訂閱基本概念使用異常來提供一致性的錯(cuò) showImg(https://segmentfault.com/img/remote/1460000013228854); Thinking ...
摘要:類最基本的作用,在于通過類獲取到相應(yīng)的對(duì)象,在向?qū)ο蟀l(fā)送消息時(shí)以期望對(duì)象做某些特定的事情。先導(dǎo)概念引用中一切皆對(duì)象,因此采用一個(gè)指向?qū)ο蟮囊脕聿倏v對(duì)象。對(duì)象可以存活于作用域之外。 歡迎各位讀者關(guān)注我的微信公眾號(hào),共同探討Java相關(guān)技術(shù)。生命不止,學(xué)習(xí)不休! showImg(https://segmentfault.com/img/bVboaBO?w=129&h=129); 也許你慢...
摘要:寫這篇總結(jié),主要是記錄下自己的學(xué)習(xí)經(jīng)歷,算是自己對(duì)知識(shí)的一個(gè)回顧。這個(gè)階段學(xué)習(xí)的時(shí)候,要學(xué)會(huì)使用開發(fā)工具,比如或者來學(xué)習(xí)。這個(gè)階段需要自己對(duì)自己有很強(qiáng)的自律去學(xué)習(xí),不要看了一半就放棄了。 showImg(https://segmentfault.com/img/bVbaNtw?w=1232&h=822); 寫這篇總結(jié),主要是記錄下自己的學(xué)習(xí)經(jīng)歷,算是自己對(duì)知識(shí)的一個(gè)回顧。也給想要學(xué)習(xí) ...
摘要:寫這篇總結(jié),主要是記錄下自己的學(xué)習(xí)經(jīng)歷,算是自己對(duì)知識(shí)的一個(gè)回顧。這個(gè)階段學(xué)習(xí)的時(shí)候,要學(xué)會(huì)使用開發(fā)工具,比如或者來學(xué)習(xí)。這個(gè)階段需要自己對(duì)自己有很強(qiáng)的自律去學(xué)習(xí),不要看了一半就放棄了。 showImg(https://segmentfault.com/img/bVbaNtw?w=1232&h=822); 寫這篇總結(jié),主要是記錄下自己的學(xué)習(xí)經(jīng)歷,算是自己對(duì)知識(shí)的一個(gè)回顧。也給想要學(xué)習(xí) ...
閱讀 3083·2021-11-24 10:21
閱讀 1691·2021-10-11 10:57
閱讀 2868·2021-09-22 15:24
閱讀 2762·2021-09-22 14:58
閱讀 2389·2019-08-30 13:16
閱讀 3572·2019-08-29 13:05
閱讀 3472·2019-08-29 12:14
閱讀 3526·2019-08-27 10:55