摘要:總結異常總的來說還是很重要的,也是保障程序健壯性很重要的一欄,并且可以達到立竿見影的效果,這里只是基本總結了異常的一些常見問題,很多還得在自己運用的過程中去探索。
概述
說起異常,我就想起了Bug,也就是常說的信春哥,無Bug,什么是Bug呢?我理解的Bug就是沒有按照自己原先假想的邏輯去執行,這其中包括了兩個方面,一方面是代碼語法問題,一方面是邏輯問題,就比如正常邏輯買了東西要付款,但是買家買了東西卻沒有付款,直接拿東西走了,這是邏輯問題,或者是本來數組存儲3個元素,你卻存了4個,這時候也出現了Bug,程序報錯了,這種Bug就是異常。
異常也是Java類的一種,用new創建對象,他們的結構是這樣的:
Throwable
error
Exception
恩,就是這樣,異常分為錯誤和異常,感覺有點繞口,但就是這樣,像error這種錯誤是在編譯期間就會報出來的,如果你使用的是IDE,所以我們只需要關注Exception異常就可以了。
獲取異常和處理異常獲取和處理異常可能就是異常的全部,我們的一個原則就是:
發生異常就得讓程序員知道
獲取異常怎么獲取異常呢?Java給出了try關鍵字用來解決,我們只需要將可能出現異常的代碼放在try中就可以了,就像這樣:
try{ ... }
java給出了盡量優雅的解決方案來處理異常,它不希望處理異常的代碼和本身的業務代碼有過多的混合,獲取到異常就該處理異常,這時候就應該這樣寫了:
try{ ... }catch(Type1 type1){ ... }catch(Type2 type2){ ... }
catch中的type代表了在try中可能出現的異常類型
catch如何匹配異常?
按順序從第一個到最后一個,如果發現異常匹配,就停止匹配,和switch模式不一樣
基類包含子類異常,如果第一個是Exception,那么后面的都不用匹配了
那么catch中怎么處理這個異常呢?
不作處理(會出現“吞食”)
打印到控制臺
寫入日志
繼續向上拋
在try塊中拋出異常,我們在catch中會匹配到相應的異常類型,這時候我們就會拿到對應的異常對象的引用,我們調用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
每個人處理處理異常的方式可能不盡相同
我們除了可以使用try來捕獲異常,我們也可以將這個異常拋出去,我們可以把異常比作現在這種制度,地球村出了點問題,村長衡量了一下,覺得這事情自己處理不了,就交給鄉長了,這種把問題交給上層或者是Java編程思想中說的跳出當前環境,交給一個更大的環境去處理,這也是Java異常處理的一種思路。
if(t == null) throw new NullPointerException();
其實異常最重要的就是異常的名稱,現在Java正在擴充異常的種類,但是很多異常可能不是我們想要的,那么我們就可以自定義異常:
class SystemErrException extends Exception{ }
這就是一個異常類,我們繼承了Exception,這個SysteErrException就可以用于我們處理異常的時候了,當然我們可以給他加點參數:
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; } }
這只不過是多加了幾個參數,但是這些一般是沒什么必要的。
throws說到這,就得說另一個關鍵字throws,看清楚,不是throw,而是throws,這可能也是面試新手的時候會問的一個問題,throws是異常中的一個申明,在IO學習中會非常常見,它是一個聲明,編譯器檢查到說你這段代碼可能會發生什么異常,你要聲明一下,這時候你就要在方法上聲明:
public void inputFile() throws IOException{ .... }finally
finally用處就和他的意思相符,表示最終的含義,也就是finally里面的代碼一定會得到執行:
案例一
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{ }
執行結果:
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); } } }
執行結果:
start....... 1 end start....... 1 2 end start....... 1 2 3 end最佳實踐
我們可能遇到這種情況,打開一個文件,讀取文件,關閉文件,正常邏輯是這樣的,但是這樣會有幾個問題:
在打開文件的過程中出現異常,但是還要關閉文件
就像這樣:
try{ A a = new A(); ... }catch(){ ... }finally{ a.close(); }
A在創建過程中會出現異常,但是還是會執行a的方法,比如關閉文件
所以我們應該這么做:
try{ A a = new A(); try{ ... }finally{ a.close(); } }catch(){ ... }異常棧
一般報錯都會報一大堆錯誤,大家無從看起,其實異常報錯也是有規律的,這就是棧結構,先進后出,舉個栗子:
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("---------------------------"); } }
運行結果:
f main --------------------------- f g main --------------------------- f g h main ---------------------------
可以看到異常信息都是從內到外的,按我的理解查看異常的時候要從第一條異常信息看起,因為那是異常發生的源頭。
總結異常總的來說還是很重要的,也是保障程序健壯性很重要的一欄,并且可以達到立竿見影的效果,這里只是基本總結了異常的一些常見問題,很多還得在自己運用的過程中去探索。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/65147.html
摘要:前言編程思想這本書,陸陸續續讀了年,終于基本都瀏覽了一遍。每個對象對外暴露接口,程序通過對象暴露的接口向對象發送消息,獲取該對象的服務能力。異常處理異常處理,為編寫程序階段提供了一種預見性的防止程序崩潰的出路。 前言 《Java編程思想》這本書,陸陸續續讀了1年,終于基本都瀏覽了一遍。通過這本書,試圖理解作者的想法,才真的體會到Java思想。感謝本書的作者,不僅講述了java的語法,更...
摘要:系列博文目錄編程思想學習錄連載之一切都是對象編程思想學習錄連載之初始化與清理編程思想學習錄連載之內部類編程思想學習錄連載之異常本篇文章將講述關于異常的相關知識注本文首發于公眾號,可長按或掃描下面的小心心來訂閱基本概念使用異常來提供一致性的錯 showImg(https://segmentfault.com/img/remote/1460000013228854); Thinking ...
摘要:類最基本的作用,在于通過類獲取到相應的對象,在向對象發送消息時以期望對象做某些特定的事情。先導概念引用中一切皆對象,因此采用一個指向對象的引用來操縱對象。對象可以存活于作用域之外。 歡迎各位讀者關注我的微信公眾號,共同探討Java相關技術。生命不止,學習不休! showImg(https://segmentfault.com/img/bVboaBO?w=129&h=129); 也許你慢...
摘要:寫這篇總結,主要是記錄下自己的學習經歷,算是自己對知識的一個回顧。這個階段學習的時候,要學會使用開發工具,比如或者來學習。這個階段需要自己對自己有很強的自律去學習,不要看了一半就放棄了。 showImg(https://segmentfault.com/img/bVbaNtw?w=1232&h=822); 寫這篇總結,主要是記錄下自己的學習經歷,算是自己對知識的一個回顧。也給想要學習 ...
摘要:寫這篇總結,主要是記錄下自己的學習經歷,算是自己對知識的一個回顧。這個階段學習的時候,要學會使用開發工具,比如或者來學習。這個階段需要自己對自己有很強的自律去學習,不要看了一半就放棄了。 showImg(https://segmentfault.com/img/bVbaNtw?w=1232&h=822); 寫這篇總結,主要是記錄下自己的學習經歷,算是自己對知識的一個回顧。也給想要學習 ...
閱讀 3019·2021-11-24 10:21
閱讀 1588·2021-10-11 10:57
閱讀 2803·2021-09-22 15:24
閱讀 2659·2021-09-22 14:58
閱讀 2331·2019-08-30 13:16
閱讀 3478·2019-08-29 13:05
閱讀 3411·2019-08-29 12:14
閱讀 3441·2019-08-27 10:55