java面試題(楊曉峯)---第二講Exception和Error有什麼區別?

本人總結:java

Exception和Error:正常問題和意外問題,以自行車舉例:沒氣和爆胎.程序員

①理解Throwable,Exception,Error的設計和分類.面試

②掌握哪些應用最普遍的子類,編程

③如何定義異常.編程語言

 

解決不了異常的捕獲不如拋出.函數

捕獲不了異常的捕獲不是好捕獲,什麼異常都捕獲的捕獲不是好捕獲,解決不了異常的捕獲必定是壞捕獲.編碼

捕獲不是俄羅斯轉盤,99分的捕獲不如拋出,由於缺的1分多是致命的.spa

 

世界上存在永遠不會出錯的程序嗎?這也許只會出如今程序員的夢中.隨着編程語言和軟件的誕生,異常狀況就如影隨形的糾纏着咱們,只有正確吃力好意外狀況,才能保證程序的可靠性.設計

 java語言在設計之初就提供了相對完整的異常處理機制,這也是java得意大行其道的緣由之一,由於這種機制大大下降了編寫和維護可靠程序的門檻.現在,異常處理機制已經成爲現代編程語言的標配.調試

 今天的問題:
請對比Exception和Error,另外,運行時異常與通常異常有什麼區別?

經典回答

Exception和Error都是繼承了Throwable類,在java中只有Throwable類型的實例才能夠被拋出(throw)或者捕獲(catch),它是異常處理機制的基本組成類型.

Exception和Error體現了java平臺設計者對不一樣異常狀況的分類.

Exception是程序正常執行中,能夠預料的意外狀況,應該被捕獲,進行相應處理.

Error是指正常狀況下,不大可能出現的狀況.絕大部分的Error都會致使程序(好比JVM自身)處於非正常,不可恢復狀態.既然是非正常狀態所以也不便於,不須要捕獲,常見如:outofmemoryerror等Error子類.

exception分爲:可檢查異常和不檢查異常.

可檢查異常:在源代碼中必須顯示的進行捕獲處理,這是編譯期檢查的一部分.

不檢查異常:(運行時異常):例如空值越界.一般是經過編碼能夠避免的邏輯錯誤,根據具體需求判斷是否捕獲,並不會在編譯期強制要求.

考點分析:

分析Exception和Error的區別,從概念角度考察了java處理機制,總的來講,還處於理解的層面,面試者只要解釋清楚就好.

咱們在平常編程中,如何處理好異常是比較考驗功底的,我以爲須要掌握兩個方面

第一,理解Throwable,Exception,Error的設計和分類.好比,掌握哪些應用最普遍的子類,以及如何定義異常.

不少面試官會進一步追問一些細節,好比,你瞭解哪些Exception,Error,RunTimeException?我簡單畫了一個圖以供參考.

 

 

 

重點理解NoClassDefFoundError和ClassNotFoundException有什麼區別,也是經典的入門題目.

第二,理解java語言中操做Throwable的元素和實踐.要掌握最基本的語法.如try-catch-finally塊,throw,throws關鍵字等.同時,懂得解決經典場景問題.

異常處理代碼比較繁瑣,如要寫千篇一概的捕獲代碼,或在finally作一些資源回收工做.隨着java語言的發展引入一些更便利的特徵,好比  try-with-resources和multiple catch,在編譯時期會自動生成對應的處理邏輯.例如,自動按約定俗成close哪些拓展了AutoCloseable或者Closeable的對象.

知識拓展

前面談的大多數是概念性的知識,下面談談實踐中的選擇,我會結合帶嗎進行分析.     

第一個:下面代碼反應異常處理中哪些不當之處:

try{ //業務代碼
Thread.sleep(1000L) }catch(Exception e){ //lgnore it
}

 

這段代碼很短,但違反了兩個基本原則

第一:儘可能不要捕獲Exception這樣的通用異常,而是要捕獲特定異常,其中Thread.sleep()拋出InterruotedException.

這是由於在平常的開發和合做中,咱們讀代碼的機會每每超過寫代碼.軟件工程是一門協做的藝術,因此咱們有義務讓本身的代碼直觀體現儘可能多的信息,可是泛泛的Exception之類,偏偏隱藏了咱們的目的.另外,咱們須要保證程序不會捕獲咱們不但願的異常.好比咱們但願RuntimeException被擴散出去,而不是被捕獲.更進一步講,除非通過深思熟慮,不然不要捕獲Throwable或者Error,由於很難保證正確處理OutOfMemoryError

第二,不要生吞異常,就是沒有完整解決異常.catch裏的內容沒有解決try拋出的問題.這樣可能致使難以診斷的詭異狀況.

生吞異常,基於假設這個異常不會發生,或者以爲忽略異常是無所謂的,可是千萬不要在產品代碼作這種假設.

若是咱們不把異常拋出來,或者也沒有輸出到日誌之類,程序可能在後續代碼以不可控方式結束.沒人能夠判斷究竟哪裏拋出異常,以及什麼緣由致使異常.

第二個:

try{ //業務
}catch(IOException e){ e.printStackTrace(); }

 這段代碼做爲一段實驗代碼沒有任何問題,但在產品代碼中一般不容許這樣處理.由於標準出錯(STERR)不是一個合適的輸出選項,由於很難判斷出到底輸出到哪裏去了.

 

 

 

公衆號:代碼榮耀

在java世界裏,異常的出現讓咱們編寫的程序運行起來更加健壯,同時爲程序在調試,運行期間發生的一些意外狀況,提供補救機會,即便遇到一些嚴重錯誤而沒法補救,異常也會很是忠實的記錄所發生的一切,

①不要推諉或延遲異常處理,就地解決最好,而且要進行實實在在的處理,而不是隻是捕捉不作動做,

②一個函數儘管拋出了多個異常,可是隻有一個異常可被傳播到客戶端,最後被拋出的異常是惟一被調用端接收的異常,其餘異常會被忽略,若是調用端要知道形成失敗的最初緣由,程序之中就不能掩蓋任何異常.

③不要在finally代碼塊中處理返回值.

④按照咱們程序員的慣性認知:當遇到return語句的時候,執行函數會馬上返回.可是,在java語言中,若是存在finally就會有例外,除了return語句,try代碼塊的break或continue語句也可能使控制權進入finally代碼塊.

⑤請勿在try代碼塊中調用return,break,continue語句.萬一沒法避免,必定要確保finally的存在不會改變函數的返回值.

⑥函數返回值有兩種類型:值類型與對象引用。對於對象引用要特別當心,若是在finally代碼塊中對函數返回的對象成員屬性進行修改,即便不在finally塊中顯式調用return語句,這個修改也做用於返回值上,

⑦誤將異經常使用於控制流。

⑧如無必要,勿用異常。

相關文章
相關標籤/搜索