Throwable的兩個子類:Error/Exception(面試中異常體系和JavaError問題)

1、error和exception有什麼區別

  • error表示系統級的錯誤,是java運行環境內部錯誤或者硬件問題,不能指望程序來處理這樣的問題,除了退出運行外別無選擇,它是Java虛擬機拋出的。

  • exception 表示程序需要捕捉、需要處理的異常,是由與程序設計的不完善而出現的問題,程序必須處理的問題。

2、運行時異常和一般異常有何不同

Java提供了兩類主要的異常:runtimeExceptioncheckedException

一般異常(checkedException)主要是指IO異常、SQL異常等。對於這種異常,JVM要求我們必須對其進行cathc處理,所以,面對這種異常,不管我們是否願意,都是要寫一大堆的catch塊去處理可能出現的異常。

運行時異常(runtimeException)我們一般不處理,當出現這類異常的時候程序會由虛擬機接管。比如,我們從來沒有去處理過NullPointerException,而且這個異常還是最常見的異常之一。

出現運行時異常的時候,程序會將異常一直向上拋,一直拋到遇到處理代碼,如果沒有catch塊進行處理,到了最上層,如果是多線程就由**Thread.run()拋出,如果不是多線程那麼就由main.run()**拋出。拋出之後,如果是線程,那麼該線程也就終止了,如果是主程序,那麼該程序也就終止了。

其實運行時異常的也是繼承自Exception,也可以用catch塊對其處理,只是我們一般不處理罷了,也就是說,如果不對運行時異常進行catch處理,那麼結果不是線程退出就是主程序終止

如果不想終止,那麼我們就必須捕獲所有可能出現的運行時異常。如果程序中出現了異常數據,但是它不影響下面的程序執行,那麼我們就該在catch塊裏面將異常數據捨棄,然後記錄日誌。如果,它影響到了下面的程序運行,那麼還是程序退出比較好些。

3. 什麼是Java異常

答:異常是發生在程序執行過程中阻礙程序正常執行的錯誤事件。比如:用戶輸入錯誤數據、硬件故障、網絡阻塞等都會導致出現異常。 只要在Java語句執行中產生了異常,一個異常對象就會被創建,JRE就會試圖尋找異常處理程序來處理異常。如果有合適的異常處理程序,異常對象就會被異常處理程序接管,否則,將引發運行環境異常,JRE終止程序執行。 Java異常處理框架只能處理運行時錯誤,編譯錯誤不在其考慮範圍之內。

4. Java中的檢查型異常和非檢查型異常有什麼區別?

這又是一個非常流行的Java異常面試題,會出現在各種層次的Java面試中。檢查型異常和非檢查型異常的主要區別在於其處理方式。檢查型異常需要使用try, catch和finally關鍵字在編譯期進行處理,否則編譯器會報錯。對於非檢查型異常則不需要這樣做。Java中所有繼承自java.lang.Exception類的異常都是檢查型異常,所有繼承自RuntimeException的異常都被稱爲非檢查型異常(運行時異常)。

5. Java中的NullPointerException和ArrayIndexOutOfBoundException之間有什麼相同之處?

在Java異常面試中這並不是一個很流行的問題,但會出現在不同層次的初學者面試中,用來測試應聘者對檢查型異常和非檢查型異常的概念是否熟悉。順便說一下,該題的答案是,這兩個異常都是非檢查型異常,都繼承自RuntimeException。該問題可能會引出另一個問題,即Java和C的數組有什麼不同之處,因爲C裏面的數組是沒有大小限制的,絕對不會拋出ArrayIndexOutOfBoundException。

6. 在Java異常處理的過程中,你遵循的那些最好的實踐是什麼?

這個問題在面試技術經理是非常常見的一個問題。因爲異常處理在項目設計中是非常關鍵的,所以精通異常處理是十分必要的。異常處理有很多最佳實踐,下面列舉集中,它們提高你代碼的健壯性和靈活性:

  1. 調用方法的時候返回布爾值來代替返回null,這樣可以 NullPointerException。

  2. catch塊裏別不寫代碼。空catch塊是異常處理裏的錯誤事件,因爲它只是捕獲了異常,卻沒有任何處理或者提示。通常你起碼要打印出異常信息,當然你最好根據需求對異常信息進行處理。

3)能拋受控異常(checked Exception)就儘量不拋受非控異常(unchecked Exception)。通過去掉重複的異常處理代碼,可以提高代碼的可讀性。

  1. 絕對不要讓你的數據庫相關異常顯示到客戶端。由於絕大多數數據庫和SQLException異常都是受控異常,在Java中,你應該在DAO層把異常信息處理,然後返回處理過的能讓用戶看懂並根據異常提示信息改正操作的異常信息。

  2. 在Java中,一定要在數據庫連接,數據庫查詢,流處理後,在finally塊中調用**close()**方法。

7. 既然我們可以用RuntimeException來處理錯誤,那麼你認爲爲什麼Java中還存在檢查型異常?

這是一個有爭議的問題,在回答該問題時你應當小心。雖然他們肯定願意聽到你的觀點,但其實他們最感興趣的還是有說服力的理由。我認爲其中一個理由是,存在檢查型異常是一個設計上的決定,受到了諸如C++等比Java更早的編程語言設計經驗的影響。絕大多數檢查型異常位於java.io包內,這是合乎情理的,因爲在你請求了不存在的系統資源的時候,一段強壯的程序必須能夠優雅的處理這種情況。通過把IOException聲明爲檢查型異常,Java 確保了你能夠優雅的對異常進行處理。另一個可能的理由是,可以使用catch或finally來確保數量受限的系統資源(比如文件描述符)在你使用後儘早得到釋放。 Joshua Bloch編寫的 Effective Java 一書 中多處涉及到了該話題,值得一讀。

8. throw 和 throws這兩個關鍵字在java中有什麼不同?

一個java初學者應該掌握的面試問題。 throw 和 throws乍看起來是很相似的尤其是在你還是一個java初學者的時候。儘管他們看起來相似,都是在處理異常時候使用到的。但在代碼裏的使用方法和用到的地方是不同的。throws總是出現在一個函數頭中,用來標明該成員函數可能拋出的各種異常, 你也可以申明未檢查的異常,但這不是編譯器強制的。如果方法拋出了異常那麼調用這個方法的時候就需要將這個異常處理。另一個關鍵字 throw 是用來拋出任意異常的,按照語法你可以拋出任意 Throwable (i.e. Throwable 或任何Throwable的衍生類) , throw可以中斷程序運行,因此可以用來代替return . 最常見的例子是用 throw 在一個空方法中需要return的地方拋出 UnSupportedOperationException 代碼如下 :

private static void show() {  
     throw new UnsupportedOperationException("Not yet implemented");
 }

9. 什麼是“異常鏈”?

“異常鏈”是Java中非常流行的異常處理概念,是指在進行一個異常處理時拋出了另外一個異常,由此產生了一個異常鏈條。該技術大多用於將“ 受檢查異常” ( checked exception)封裝成爲“非受檢查異常”(unchecked exception)或者RuntimeException。順便說一下,如果因爲因爲異常你決定拋出一個新的異常,你一定要包含原有的異常,這樣,處理程序纔可以通過getCause()和initCause()方法來訪問異常最終的根源。

10. 你曾經自定義實現過異常嗎?怎麼寫的?

很顯然,我們絕大多數都寫過自定義或者業務異常,像AccountNotFoundException。在面試過程中詢問這個Java異常問題的主要原因是去發現你如何使用這個特性的。這可以更準確和精緻的去處理異常,當然這也跟你選擇checked 還是unchecked exception息息相關。通過爲每一個特定的情況創建一個特定的異常,你就爲調用者更好的處理異常提供了更好的選擇。相比通用異常(general exception),我更傾向更爲精確的異常。大量的創建自定義異常會增加項目class的個數,因此,在自定義異常和通用異常之間維持一個平衡是成功的關鍵。

11. JDK7中對異常處理做了什麼改變?

這是最近新出的Java異常處理的面試題。JDK7中對錯誤(Error)和異常(Exception)處理主要新增加了2個特性,一是在一個catch塊中可以出來多個異常,就像原來用多個catch塊一樣。另一個是自動化資源管理(ARM), 也稱爲try-with-resource塊。這2個特性都可以在處理異常時減少代碼量,同時提高代碼的可讀性。對於這些特性瞭解,不僅幫助開發者寫出更好的異常處理的代碼,也讓你在面試中顯的更突出。

12. 如果執行finally代碼塊之前方法返回了結果,或者JVM退出了,finally塊中的代碼還會執行嗎?

這個問題也可以換個方式問:“如果在try或者finally的代碼塊中調用了System.exit(),結果會是怎樣”。瞭解finally塊是怎麼執行的,即使是try裏面已經使用了return返回結果的情況,對了解Java的異常處理都非常有價值。只有在try語句塊裏面是用System.exit(0)來退出JVM的情況下finally塊中的代碼纔不會執行。

13. Java中final,finalize,finally關鍵字的區別

  • 這是一個經典的Java面試題了。我的一個朋友爲Morgan Stanley招電信方面的核心Java開發人員的時候就問過這個問題。final和finally是Java的關鍵字,而finalize則是方法。final關鍵字在創建不可變的類的時候非常有用,只是聲明這個類是final的。而finalize()方法則是垃圾回收器在回收一個對象前調用,但也Java規範裏面沒有保證這個方法一定會被調用。finally關鍵字是唯一一個和這篇文章討論到的異常處理相關的關鍵字。在你的產品代碼中,在關閉連接和資源文件的是時候都必須要用到finally塊。

  • 每個Java中方法的覆蓋是有規則的,一個覆蓋的方法不能拋出的異常比原方法繼承關係高。因爲這裏的start方法在超類中拋出了IOException,所有在子類中的start方法只能拋出要麼是IOExcepition或是其子類,但不能是其超類,如Exception。

14. 常用的異常列表

在這裏插入圖片描述

15. 你平時在項目中是怎樣對異常進行處理的。

(1)儘量避免出現runtimeException 。例如對於可能出現空指針的代碼,帶使用對象之前一定要判斷一下該對象是否爲空,必要的時候對runtimeException也進行try catch處理。

(2)進行try catch處理的時候要在catch代碼塊中對異常信息進行記錄,通過調用異常類的相關方法獲取到異常的相關信息,返回到web端,不僅要給用戶良好的用戶體驗,也要能幫助程序員良好的定位異常出現的位置及原因。例如,以前做的一個項目,程序遇到異常頁面會顯示一個圖片告訴用戶哪些操作導致程序出現了什麼異常,同時圖片上有一個按鈕用來點擊展示異常的詳細信息給程序員看的。

16. final、finally、finalize的區別

(1)、final用於聲明變量、方法和類的,分別表示變量值不可變,方法不可覆蓋,類不可以繼承

(2)、finally是異常處理中的一個關鍵字,表示finally{}裏面的代碼一定要執行

(3)、finalize是Object類的一個方法,在垃圾回收的時候會調用被回收對象的此方法。

17. try()裏面有一個return語句,那麼後面的finally{}裏面的code會不會被執行,什麼時候執行,是在return前還是return後?

只要沒有在try塊中顯式調用System.exit()退出JVM,那麼finally塊中的語句一定會執行。return會返回finally塊中的return信息。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章