java異常類java
java.lang.Throwablec++
方法:程序員
getMessage(); 得到異常描述編程
printStackTrance(); 打印異常堆棧數組
關於Throwable網絡
** StackTraceElement。一個final類,表明棧軌跡中的元素,一個異常可能有多個元素。測試
一.打印棧軌跡的方法this
- 主動調用Throwable對象的printStackTrace()=printStackTrace(System.err),printStackTrace(PrintStream),printStackTrace(PrintWriter)中的其中一個。
- 若是一個Exception沒有被處理,直接在main方法後面throws,程序退出前將調用異常的printStackTrace()方法,最終是Exception in thread "main" + printStackTrace()
棧軌跡設計
- 棧軌跡顯示了"把你帶到異常拋出的地點"。
- 上面三個方法調用this.getOurStackTrace()得到棧軌跡;同時Throwable提供了public的方法getStackTrace()得到棧軌跡(實際返回getOurStackTrace().clone())。
- getStackTrace()將返回棧軌跡中元素所構成的數組,其中每個元素都是一幀。元素0是棧頂元素,棧頂元素爲調用序列裏的最後一個方法,棧底元素是第一個方法。
fillInStackTrace方法調試
- native fillInStackTrace()方法將返回一個Throwable對象,它是經過把當前調用棧信息填入原來那個異常對象兒創建的,因此返回的仍是原來的異常。
- 調用此方法的那一行將成爲異常新的發生地,有關原來異常發生點的信息會丟失。它的效果等價於捕獲一個異常後,從新拋出另一種異常。二者不一樣的 是,fillInStackTrace後的異常仍是原來的異常(只是少了棧軌跡而已);而從新拋出一個異常的話,徹底跟原異常信息無關了(固然也沒有棧軌 跡)。
異常鏈
- 經常會再捕獲一個異常後拋出另一個異常,而且但願把異常原始信息保存下來,這被稱爲異常鏈。
- 在JDK1.4之前,程序員必須本身編寫代碼來保存原始異常信息,
- 如今全部Throwable的子類子構造器中均可以接受一個cause對象做爲參數,這個cause就異常起因,表明着原始異常,即便在當前位置建立並拋出行的異常,也能夠經過這個cause追蹤到異常最初發生的位置。
- 只有Error,Exception,RunimeException提供了帶cause參數的構造器,其餘的因此異常就只有經過initCause()來設置cause了。
effective java 和think in java
think in java
- 發現錯誤的最佳時期是編譯期間,然而編譯期間並不能找出全部數據,餘下的問題必須在運行期間解決。
- switch case語句裏若是throw Exception的話是不須要break的。
- 異常處理理論上有兩種基本模型。終止模型,java和c++支持的模型,將假設錯誤很是關鍵,一旦異常被拋出,就代表錯誤已經沒法挽回,也不能繼續執行;恢復模型,遇到錯誤不能拋出異常,而是調用方法來修正錯誤。
- 儘可能不要捕獲RuntimeException,但仍是能夠在代碼中拋出RuntimeException類型的異常。
- 若是一個方法只申明瞭異常,但並無在方法體拋出任何異常,調用此方法的方法是沒有異常能夠捕獲的。
- 丟失異常:1.不使用異常鏈;2.從finally語句返回。
- 異常的限制:1.父類異常大於等於子類異常,子類要麼不拋,要麼拋出父類異常或父類異常的子異常。2.若是一個對象聲明爲父類引用時,調用此對象的方法, 拋出父類裏聲明的異常;若是一個對象聲明爲是本身引用時,調用此對象的方法,固然拋出本身聲明的異常,跟父類無關。3.異常聲明不是方法簽名的一部分,方 法簽名由方法名字和參數個數及類型組成,因此異常聲明不能做爲重載的判斷標準。4.構造器能夠拋出任何異常,而沒必要理會父類構造器拋了什麼異常。
- 在建立須要清理的對象以後,當即進入try-finally塊清理此對象
- 異常匹配順序:找出最近的異常;子類的對象也能夠匹配其父類的處理程序。找到匹配的後,再也不繼續查找。
- 異常的重要準則是隻有在你知道如何處理的狀況下才捕獲異常。重要目標是把錯誤處理的代碼同錯誤發生的地點相分離。舉個列子service-dao兩層,在 dao裏產生了SQLException我無需處理直接拋出,到了service層,我知道要將其轉換成本身的業務異常。
effective java
- 基於異常的模式:用try catch而後忽略異常的手段來達到你想要的目的。
- 異常應該只用於異常的狀況下,它們永遠不該該用於正常的控制流。對此我不贊同。、
- 對可恢復的狀況使用受檢異常,對編程錯誤使用運行時異常。何爲可恢復的狀況,是指不改變代碼的基礎上,這個異常狀況是能夠恢復的,比喻 IOExcepion多是網絡的問題,解決了網絡,代碼就能繼續運行下去了;何爲錯誤,固然指不能恢復的啦,比喻從你控制範圍以外傳遞進來的null引 用,因此,此類異常都是程序員的問題,做爲程序員,應該在代碼中進行必要的檢查。
- 異常類越少,意味着內存印跡就越小,裝載這些類的時間開銷也越少。
- 異常轉譯:高層的實現應該捕獲低層的異常,同時拋出能夠按照高層抽象進行解釋的異常。異常鏈就是一種特殊的異常轉譯形式,高層異常能夠經過getCause來得到低層的異常。
- 異常的細節信息應該包含全部的對該異常有貢獻的參數和域的值。比喻IndexOutOfBoundsException應該包含 lowerBound,upperBound,Index三個參數。遺憾的是Java平臺裏並無普遍的使用這種作法,而是所有清一色的簡單繼承了下父 Exception。
- 失敗原子性:失敗的方法調用應該使對象保持在調用前的狀態。若是沒有size==0的判斷,可能致使size域同以前的不一致。
try catch finally break continue return
準則
finally通常狀況總會執行,不管在try塊裏return break continue。除了調用System.exit(0)方法,該方法終止java虛擬機進程。
try塊裏return以前,finally會被執行
return語句會把後面的值複製到一份用來返回,若是return的是基本類型的,finally裏對變量的改動將不起效果,若是return的是引用 類型的,改動將能夠起效果。執行順序:將要return時調用jsr指令----->finally代碼塊,finally代碼塊最後執行ret指 令----->繼續return。
finally裏的return語句會把try塊裏的return語句效果給覆蓋掉。finally語句裏的return,break,continues,拋出異常,finally子句結尾處的ret指令永遠不會執行,不會在去調用finally的地方了。
咱們須要作的是
- 最好把return放到方法尾而不要在try裏return。
- 若是非要的話:不要在try塊和finally塊裏都包含return;若是在try塊裏return, 則不要在finally塊裏操做被return的變量。
兩個子類:
Error:僅靠程序自己沒法恢復的嚴重錯誤,好比內存不足,java虛擬機的方法調用堆棧溢出。
大多數狀況下,遇到這樣的錯誤時,程序只有死的份。
StackOverError,OutOfMemoryError
Exception:表示程序能夠處理的異常。程序出現異常的時候,應該儘量地處理異常,而且
使得程序恢復運行,而不該該隨意停止。
EOFException,FileNotFoundException
RuntimeException異常及其子類:運行時異常
java編譯器不會檢查它,這種異常沒有try catch語句捕獲,也沒有throw字句拋出,仍是編譯經過。
unchecked Exception
運行時異常表示沒法讓程序恢復運行的異常,致使這種異常的緣由一般是因爲執行了錯誤操做。一旦出現錯誤操做,建議
終止程序,所以java編譯器不檢查這種異常。
運行時異常應該儘可能避免,在程序調試階段,遇到這種異常的時候,正確的作法是改進程序的設計和實現方式,修改程序
中的錯誤,從而避免這種錯誤。
若是捕獲而且使程序恢復運行不是明智的行爲:
1.這種異常一旦發生,損失嚴重。
2.即便程序恢復運行,也可能會致使程序的業務邏輯錯亂,甚至致使更嚴重的異常,或者獲得錯誤的運行結果。
受檢異常,除了RuntimeException及其子類的全部Exception及其子類。
Checked Exception
這種異常要麼用try..catch捕獲,要麼用throw子句聲明拋出,不然編譯不會經過。
能夠處理和修復的異常,若是拋出異常的方法自己不能處理它,那麼方法調用者應該去處理,如此遞推,知道在某一層能夠處理它,
就進行必要的處理,而不至於終止程序。
Error和java運行時異常:
相同:java編譯器都不會檢查他們,當程序出現錯誤的時候,都死。
不一樣:Error及其子類是由java虛擬機拋出,通常不可拓展。
RuntimeException表示程序代碼中的錯誤,能夠自定義。
異常轉義和異常鏈
異常處理原則
1.異常只能用於非正常狀況
2.爲異常提供文檔說明
3.儘量地避免異常
**許多運行時異常是因爲代碼中的錯誤引發的,修改代碼,改進實現方式
**提供狀態測試方法,某種狀態下,不適合這種操做,引發異常。
4.保持異常的原則性
**檢查方法的參數是否有效,確保異常發生的時候尚未改變初始狀態
**恢復代碼
**在對象的臨時對象上進行操做,當操做成功後,把拷貝的內容複製到原來的對象上
5.避免過於龐大的try代碼塊
**分段處理
6.在catch子句中指定具體的異常
try{
//code
}catch(Exception e){//code}
**俗話說對症下藥,對不一樣的異常一般有不一樣的處理方式。以上代碼意味着對全部異常採用相同的方式,這每每是不現實的。
**會捕獲原本應該拋出的運行時異常,掩蓋程序中的錯誤。
7.不要在catch代碼塊中忽略被捕獲的異常
**處理異常:針對異常採起一些行動,好比彌補形成的損失或者給出警告。
**從新拋出異常:若是當前時間或者環境下還不能處理該異常,就應該從新拋出。
**進行異常轉譯:把原始異常包裝成適合當前抽象層的另外一種異常,再將其拋出。
**假如在catch代碼塊中不能採起任何措施,那麼就不要捕獲異常,而是用throws子句聲明拋出異常。