《高质量java程序设计》读书笔记之----异常处理(1)
?????? “有所為而有所不為”。學會java和學好java并用它設(shè)計并實現(xiàn)高效率的程序,這兩者相去甚遠。
?????? 異常處理是java中最強大而又最容易誤用的機制。很多人只知道大概的異常處理的語法,卻沒有體會異常到底可以用來做些什么,如何才能有效的使用異常,以及什么時候又不應該使用異常??偟膩碚f,就是“有所為”是哪些,而哪些又是“有所不為”的呢?
?????? 面對這樣一個強大的工具,我們要做的第一件事情就是對是不是要使用它做出自己的決定,而異常這個東西并不是在任何情況下都適用的。因此我們應該知道何時使用,何時不是使用異常。
?????? 而一旦決定使用異常了以后,我們又面臨一個新的問題,那就是如何去使用異常呢?
這就是我們對異常應該思考的兩個大的問題,也就是“干什么”和“怎么干”。
?????? 異常處理就是向客戶表示發(fā)生的非正常情況的機制,它和斷言一起構(gòu)成了運行時檢查的兩個重要角色。主要用于運行時錯誤(也就是程序執(zhí)行時發(fā)生的錯誤)的處理方面。這些錯誤可能是數(shù)學運算溢出,磁盤不足或者文件損壞等非正常情況。當這些錯誤發(fā)生時,程序應該要么去嘗試恢復程序的狀態(tài),要么就直接通知用戶發(fā)生了異常。
<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
?
????? 規(guī)則1 用時間頻度來確定異常情況。
????? 包含異常處理的代碼,就算沒有異常發(fā)生,也會付出額外的代價,應當從時間頻度的角度來考慮是否使用異常。對于一個方法method(),如果它的一個流程分支經(jīng)常發(fā)生,甚至每次調(diào)用都會發(fā)生,那么就不應該使用異常來進行控制。
?
?????? java的語義規(guī)則包含兩個方面的含義:一種是java類庫中內(nèi)置的語義檢查,如數(shù)組下標越界就會引發(fā)IndexOutOfBoundsException.另一種就是我們可以自己創(chuàng)建新的異常,并選擇何時用throw關(guān)鍵字來引發(fā)異常。
?????? 異常拋出后,JVM會對調(diào)用棧進行遍歷來尋找匹配的catch語句,如果最后還找不到的話,就會調(diào)用?ThreadGroup.uncaughtException()。
?????? 異常對性能的影響有兩個方面:一是異常的創(chuàng)建,捕獲和處理都需要付出代價。另一方面,就算異常沒有發(fā)生,包含異常處理的代碼也會比不包含異常處理的代碼需要的運行時間更多(這和我們所想的不一樣,原來一直以為如果不發(fā)生異常,就根本不需要為異常處理付出代價)。
?????? 說了這么多廢話,呵呵,那到底什么時候應該使用異常處理哪?答:在異常的時候使用異常處理。(^o^,先別急著罵,聽我慢慢說嘛。。。)。既然我們要使用異常處理,那最基本的一個問題就必須回答:究竟什么樣的情況才能算是異常情況,你又是用什么標準來評估的哪?我認為可以使用一個簡單的原則:時間頻度。對于一個方法method(),如果它的一個流程分支經(jīng)常發(fā)生,甚至每次調(diào)用都會發(fā)生,那么就不應該使用異常來進行控制。理由很明顯,首先,從性能上考慮,如果對這么頻繁發(fā)生的東西進行異常處理,那么程序性能肯定會受到損害。其次,既然是經(jīng)常會發(fā)生的情況,那還能叫“異常”嗎?(^o^,這不是抽自己嘴巴子嘛)。
?????? 廢話多了,也真無聊,來兩個例子先:
?????????
例1:????????FileInputStream?in;
????????try
????????{
????????????in?=?new?FileInputStream(filename);
????????}
????????catch(FileNotFoundException?ex)
????????{
????????????System.out.println("找不到文件:"+filename);
????????????return;
????????}
????????int?ch;
????????try
????????{
????????????while((ch=in.read())!=-1)
????????????{
????????????????System.out.println((char)ch);
????????????}
????????????
????????}
????????catch(IOException?ex)
????????{
????????????
????????} 例2
????????????FileInputStream?in;
????????try
????????{
????????????in?=?new?FileInputStream(filename);
????????}
????????catch(FileNotFoundException?ex)
????????{
????????????System.out.println("找不到文件:"+filename);
????????????return;
????????}
????????DataInput?din?=?new?DataInputStream(in);
????????try
????????{
????????????
????????}
????????catch(EOFException?ex)
????????{
????????????
????????}
????????catch(IOException?ex)
????????{
????????????
????????} 例3:
??????for(Iterator?i=c.iterator();ihasNext();)
????????????i.remove();
??????先來看例1,FileInputStream的read()返回-1表示到達文件結(jié)尾處,如果我們不這么用,而是對read()方法使用異常處理,那么在每次讀全部文件時就都會到達文件結(jié)尾,那么每次都要 進行異常處理,代價太大。而另一方面,使用-1來表示文件結(jié)尾不會與文件中的字符相混淆。
??????再看例2,DataInput接口的readInput(),readLong(),readFloat(),readDouble()等方法都以拋出EOFException來表示到達文件結(jié)尾了。由于可能文件中存在各種數(shù)據(jù)類型,因此不能象例1一樣用-1表示到達結(jié)尾處。而另一方面,讀到最后一個數(shù)據(jù)后,就自然到了文件結(jié)尾,而這是不需要額外的處理的。
???最后看例3,如果我們在這用異常,那么由于每次遍歷集合的時候都會遇到集合中的元素全部遍歷完的情況,那就是說每次都會拋出異常,那就顯然不能用異常了。
???從這幾個例子可以得兩種代替異常的方法:一是用特殊的返回值 。另一種是提前檢查,如例3中的Iterator.hasNext();但他們并不能完全替代異常處理,有的時候異常處理是不二之選。 《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀
總結(jié)
以上是生活随笔為你收集整理的《高质量java程序设计》读书笔记之----异常处理(1)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Asp.Net源码(转载)
- 下一篇: 某网络专业人士笔记(超级珍藏)