1.異常處理是java中唯一正式的錯誤報告機制,並且通過編譯器強制執行
2.異常情形:指阻止當前方法或作用域繼續執行的問題。能做的就是從當前的環境中跳出,把問題提交給上一級環境,這就是拋出異常時所發生的事情。
3.拋出異常的時候:
1. 同java中其他對象的創建一樣,將使用new在堆上創建異常對象
2. 當前的執行路徑被終止,並且從當前環境中彈出異常對象的引用。
之後異常處理機制接管程序,並開始尋找一個恰當的地方來繼續執行程序,這個恰當的地方就是異常處理程序(任務:將程序從錯誤狀態中恢復,以使程序能要麼換一種方式執行,要麼繼續運行下去;以關鍵字catch表示,只有匹配的catch子句才能得到執行)
4. 標準異常類都有兩個構造器
1. 默認構造器
2. 接受字符串作爲參數,以便能夠把相關信息放入異常對象的構造器
5. throw能夠任意類型的Throwable對象,Throwable是異常類型的根類
6. 異常處理機制:可以把所有動作都放在try塊裏,然後只需在一個地方就可以捕獲所有異常。
7. 異常處理理論:
1. 終止模型——java支持,一旦異常被拋出,就表明錯誤已經無法挽回,也不能回來繼續執行
2. 恢復模型
1. 異常處理程序的工作就是修正錯誤,然後重新嘗試調用出問題的方法,並認爲第二次能成功。
2. 再遇見錯誤的時候就不能拋出異常,而是調用方法來修正該錯誤。
3. 或者,把try塊放在while循環裏,這樣就不斷的進入try塊,直到得到滿意的結果。
8. 創建自定義異常——必須從已有的異常類繼承,做好是選擇意思相近的異常類繼承
1. 建立新的異常類型最簡單的方法是讓編譯器爲你產生默認構造器
2. 對異常來說,最重要的部分就是類名
9. Exception.printStackTrace():將打印“從方法調用處直到異常拋出處”的方法調用序列,發送到System.out;使用它來打印異常信息
10. 異常與記錄日誌
1. 靜態的Logger.getLogger()方法創建一個String參數相關聯的Logger對象(通常與錯誤相關的包名和類名),這個Logger對象會將其輸出發送到System.error
2. 向Logger寫入的最簡單方式是:直接調用與日誌記錄消息的級別相關聯的方法,如:server()
3. 如果將java.io.StringWriter對象傳遞給PrintWriter的構建器,通過調用toString()方法,就可以將輸出抽取成爲一個String
11. 異常說明:使用throws關鍵字,後面接一個所有潛在異常類型的列表
1. 可以聲明將拋出異常,實際上卻不拋出,這在定義抽象基類和接口的時候很重要,這樣派生類或者接口實現能夠拋出這些預先聲明的異常
2. 兩種意思:
1. 我的代碼會產生這種異常,這由你來處理
2. 我的代碼忽略了這些異常,這由你來處理
12. 被檢查的異常:在編譯時被強制檢查的異常
13. fillInStackTrace():用於在Throwable對象的內部記錄棧幀的當前狀態,返回一個Throwable對象
14. 重新拋出異常
1. 把異常拋給上一級環境中的異常處理程序,同一個try塊的後續catch子句將被忽略,高一級環境中捕獲次異常的處理程序可以從這個異常對象中得到所有信息
2. 如果只是拋出當前異常對象,printStackTrace()顯示的將是原來異常拋出點的調用棧信息;調用fillInStackTrace()方法可以更新這個信息(調用fillInStackTrace()的那一行就成爲了異常的新發生地)
15. 異常鏈:想要在捕獲一個異常後拋出另一個異常,並且把原始異常的信息保存下來(P260)
16. Throwable對象可分爲兩種類型:Error和Exception
17. RuntimeException異常——不受檢查異常,這種異常屬於錯誤,被自動捕獲,不用程序員處理;如果不被捕獲,那麼在程序退出前將調用異常的printStackTrace()
18. 當java中的異常不允許我們回到異常拋出的地點時,那麼如何處理呢?
1. 把try塊放在循環裏,就確立了一個“程序繼續執行之前必須要達到”的條件
2. 加入一個static類型的計數器或者別的裝置,使循環在放棄以前嘗試一定的次數
19. finally子句
1. 它能使程序員保證:無論try塊裏發生什麼,內存總能得到釋放。
2. 當涉及到break和continue語句的時候,finally子句也會被執行
20. 異常丟失:前一個異常還沒處理就拋出下一個異常
21. 派生類構造器不能捕獲基類構造器拋出的異常;在繼承中重寫方法時候訪問權限不能縮小,但是異常說明的接口恰恰相反,只能縮小
22. 構造器(P272)
1. 對於構造階段可能會拋出異常,並且要求清理的類,最安全的使用方式是使用嵌套的try子句
2. 清理慣用法在構造器不拋出異常的時候也該運用,基本規則:在創建需要清理的對象之後,立即進入一個try-finally語句塊
3. 對於每一個構造,都必須包含在其自己的try-finally語句塊中,並且每一個對象構造器必須都跟隨一個try-finally語句塊以確保清理
23. 異常匹配
1. 拋出異常的時候,異常處理系統會按照代碼的書寫順序找出“最近”的處理程序。找到匹配的處理程序後,就認爲異常將得到處理,然後就不再繼續查找
2. 派生類的對象也可以匹配其基類的處理程序
24. 其他可選方式
1. 異常處理的一個重要原則:只有在你知道如何處理的情況下才捕獲異常
2. ”被檢查異常”——強制你在可能還沒準備好處理錯誤的時候被迫加上catch子句,導致“吞食則有害”
1. 給main()加上異常說明,通過把它傳遞到控制檯,就不必再main()裏寫try-catch子句了
2. 把“被檢查的異常”轉換爲“不檢查的異常”
1. 大型項目中避免起初不知道如何處理“被檢查的異常”時使用
2. 即把“被檢查的異常”包裝進RuntimeException裏面
3. throw new RuntimeException(e);
4. 當你需要對其中的異常進行處理的時候,可以通過getCause()捕獲並處理特定的異常
try{
throw RuntimeException.getCause();
}catch(){
}
25. 異常使用指南:
1. 在知道該如何處理的情況下才捕獲異常
2. 解決問題並且重新調用產生異常的方法
3. 進行少許修補,然後繞過異常發生的地方繼續執行
4. 用別的數據進行計算,以代替方法預計會返回的值
5. 把當前運行環境下能做的事情儘量做完,然後把相同的異常重拋給更高層
6. 把當前運行環境下能做的事情儘量做完,然後把不同的異常重拋給更高層
7. 終止程序
8. 進行簡化
9. 讓類庫和程序更安全
26“報告”功能是異常的精髓所在。java堅定的強調所有的錯誤都以異常形式報告的這一事實。