java的異常機制面試題(轉)


轉自https://www.jianshu.com/p/2b4e02f7fa19

轉自https://www.cnblogs.com/xiaotangtang/p/4904866.html

https://blog.csdn.net/weixin_42182713/article/details/90739924

 

Java 對異常進行了分類,不同類型的異常分別用不同的 Java 類表示,所有異常的根類為 java.lang.Throwable,Throwable 下面又派生了兩個子類:Error 和 Exception,Error 表示應用程序本身無法克服和恢復的一種嚴重問題。
Exception 表示程序還能夠克服和恢復的問題,其中又分為系統異常和普通異常,系統異常是軟件本身缺陷所導致的問題,也就是軟件開發人員考慮不周所導致的問題,軟件使用者無法克服和恢復這種問題,但在這種問題下還可以讓軟件系統繼續運行或者讓軟件死掉,例如,數組腳本越界(ArrayIndexOutOfBoundsException),空指針異常(NullPointerException)、類轉換異常(ClassCastException);普通異常是運行環境的變化或異常所導致的問題,是用戶能夠克服的問題,例如,網絡斷線,硬盤空間不夠,發生這樣的異常后,程序不應該死掉。
java 為系統異常和普通異常提供了不同的解決方案,編譯器強制普通異常必須 try…catch 處理或用 throws 聲明繼續拋給上層調用方法處理,所以普通異常也稱為 checked 異常,而系統異常可以處理也可以不處理,所以,編譯器不強制用 try…catch 處理或用 throws 聲明,所以系統異常也稱為 unchecked 異常。

1.java異常架構圖

粉紅色的是受檢查的異常(checked exceptions),其必須被 try{}catch語句塊所捕獲,或者在方法簽名里通過throws子句聲明.受檢查的異常必須在編譯時被捕捉處理,命名為 CHecked Exception 是因為Java編譯器要進行檢查,Java虛擬機也要進行檢查,以確保這個規則得到遵守.
綠色的異常是運行時異常(runtime exceptions),需要程序員自己分析代碼決定是否捕獲和處理,比如 空指針,被0除...
而聲明為Error的,則屬於嚴重錯誤,需要根據業務信息進行特殊處理,Error不需要捕捉。

2.try{}里有一個return語句,那么緊跟在這個try后的finally {}里的code會不會被執行,什么時候被執行,在return前還是后?

也許你的答案是在return之前,但往更細地說,我的答案是在return中間執行,請看下面程序代碼的運行結果:

復制代碼
 1 public  classTest {  
 2   
 3     public static void main(String[] args) {  
 4        System.out.println(newTest().test());  
 5     }  
 6     staticint test()  
 7     {  
 8        int x = 1;  
 9        try  
10        {  
11            return x;  
12        }  
13        finally  
14        {  
15            ++x;  
16        }  
17     }  
18 }  
復制代碼

---------執行結果 ---------

運行結果是1,為什么呢?主函數調用子函數並得到結果的過程,好比主函數准備一個空罐子,當子函數要返回結果時,先把結果放在罐子里,然后再將程序邏輯返回到主函數。所謂返回,就是子函數說,我不運行了,你主函數繼續運行吧,這沒什么結果可言,結果是在說這話之前放進罐子里的。

3。final, finally, finalize的區別。

  final 用於聲明屬性,方法和類,分別表示屬性不可變,方法不可覆蓋,類不可繼承。

內部類要訪問局部變量,局部變量必須定義成final類型,例如,一段代碼……

 

finally是異常處理語句結構的一部分,表示總是執行。

 

finalize是Object類的一個方法,在垃圾收集器執行的時候會調用被回收對象的此方法,可以覆蓋此方法提供垃圾收集時的其他資源回收,例如關閉文件等。JVM不保證此方法總被調用

4.請寫出你最常見到的5個runtime exception。

這道題主要考你的代碼量到底多大,如果你長期寫代碼的,應該經常都看到過一些系統方面的異常,你不一定真要回答出5個具體的系統異常,但你要能夠說出什么是系統異常,以及幾個系統異常就可以了,當然,這些異常完全用其英文名稱來寫是最好的,如果實在寫不出,那就用中文吧,有總比沒有強!

所謂系統異常,就是…..,它們都是RuntimeException的子類,在jdk doc中查RuntimeException類,就可以看到其所有的子類列表,也就是看到了所有的系統異常。我比較有印象的系統異常有:NullPointerException、ArrayIndexOutOfBoundsException、ClassCastException。

5.JAVA語言如何進行異常處理,關鍵字:throws,throw,try,catch,finally分別代表什么意義?在try塊中可以拋出異常嗎?

Java 通過面向對象的方法進行異常處理,把各種不同的異常進行分類,並提供了良好的接口。在 Java 中,每個異常都是一個對象,它是 Throwable 類或其它子類的實例。當一個方法出現異常后便拋出一個異常對象,該對象中包含有異常信息,調用這個對象的方法可以捕獲到這個異常並進行處理。Java 的異常處理是通過 5 個關鍵詞來實現的:try、catch、throw、throws 和 finally。一

般情況下是用 try 來執行一段程序,如果出現異常,系統會拋出(throws)一個異常,這時候你可以通過它的類型來捕捉(catch)它,或最后(finally)由缺省處理器來處理;

 try 用來指定一塊預防所有“異常”的程序;

 catch 子句緊跟在 try 塊后面,用來指定你想要捕捉的“異常”的類型;

 throw 語句用來明確地拋出一個“異常”;

 throws 用來標明一個成員函數可能拋出的各種“異常”;

 Finally 為確保一段代碼不管發生什么“異常”都被執行一段代碼;

 可以在一個成員函數調用的外面寫一個 try 語句,    在這個成員函數內部寫另一個 try 語句保護其他代碼。每當遇到一個 try 語句,“異常”的框架就放到堆棧上面,直到所有的 try 語句都完成。如果下一級的 try 語句沒有對某種“異常”進行處理,堆棧就會展開,直到遇到有處理這種“異常”的 try 語句。

6.運行時異常與一般異常有何異同?

異常表示程序運行過程中可能出現的非正常狀態,運行時異常表示虛擬機的通常操作中可能遇到的異常,是一種常見運行錯誤。java編譯器要求方法必須聲明拋出可能發生的非運行時異常,但是並不要求必須聲明拋出未被捕獲的運行時異常。

7..下面的程序代碼輸出的結果是多少?

public class  smallT{

         public static void  main(String args[]){

                   smallT t  = new smallT();

                   int  b =  t.get();

                   System.out.println(b);

         }

         public int  get()

         {

                   try     {return 1;}

                   finally{return 2;}

         }}

返回的結果是2。

我可以通過下面一個例子程序來幫助我解釋這個答案,從下面例子的運行結果中可以發現,try中的return語句調用的函數先於finally中調用的函數執行,也就是說return語句先執行,finally語句后執行,所以,返回的結果是2。Return並不是讓函數馬上返回,而是return語句執行后,將把返回結果放置進函數棧中,此時函數並不是馬上返回,它要執行finally語句后才真正開始返回。

在講解答案時可以用下面的程序來幫助分析:

public  class Test {

    public static void main(String[]args) {

        System.out.println(new Test().test());;

    }

    int test()

    {

        try         {return func1();}

        finally    {return func2();}

    }

   

    int func1()

    {

        System.out.println("func1");

        return 1;

    }

    int func2()

    {

        System.out.println("func2");

        return 2;

    }  

}

-----------執行結果-----------------

func1

func2

2

結論:finally中的代碼比return 和break語句后執行

 

引言

Exception 和 Error 都是繼承了Throwable類,在java中只有Throwable的實例才能被拋出或者捕獲。
Error不能恢復java程序也不應該被捕獲。
Exception分為可檢查和不可檢查的類型,可檢查的異常應該在編碼期間顯式捕獲,因為虛擬機會在編譯期進行檢查。不檢查異常是指類似 NullPointerException、ArrayIndexOutOfBoundsException

深入理解異常

 
image.png

Error和Exception都繼承於Throwable。

ClassNotFoundException和NoClassDefFoundError的區別??

首先NoClassDefFoundError是一個錯誤(Error),而ClassNOtFoundException是一個異常,ClassNotFoundException的產生原因:
Java支持使用Class.forName方法來動態地加載類,任意一個類的類名如果被作為參數傳遞給這個方法都將導致該類被加載到JVM內存中,如果這個類在類路徑中沒有被找到,那么此時就會在運行時拋出ClassNotFoundException異常。
另外還有一個導致ClassNotFoundException的原因就是:當一個類已經某個類加載器加載到內存中了,此時另一個類加載器又嘗試着動態地從同一個包中加載這個類。
NoClassDefFoundError產生的原因:
如果JVM或者ClassLoader實例嘗試加載(可以通過正常的方法調用,也可能是使用new來創建新的對象)類的時候卻找不到類的定義。要查找的類在編譯的時候是存在的,運行的時候卻找不到了。這個錯誤往往是你使用new操作符來創建一個新的對象但卻找不到該對象對應的類。這個時候就會導致NoClassDefFoundError.

處理異常

1.不要捕獲通用異常,而是要捕獲特定異常
2.不要不要生吞異常
3.Throw early, catch late,盡早在能避免異常的時候拋出異常,然后再處理異常
4.自定義異常的時候,考慮是否要定義成可檢查異常,因為這種異常是考慮到可以從異常中恢復制定的。另外自定義異常的時候考慮盡量不要包含敏感信息
5.java的異常處理機制中try-catch 階段會產生額外的開銷,影響JVM對代碼的優化,不要用異常處理。另外每生成一個異常,jvm都會對當前棧進行快照,(個人理解是:棧快照是棧內操作的集合,用來記錄棧操作的

  1. 一個函數盡管拋出了多個異常,但是只有一個異常可被傳播到調用端。最后被拋出的異常時唯一被調用端接收的異常,其他異常都會被吞沒掩蓋。如果調用端要知道造成失敗的最初原因,程序之中就絕不能掩蓋任何異常。
    7.當遇到return語句的時候,執行函數會立刻返回。但是,在Java語言中,如果存在finally就會有例外。除了return語句,try代碼塊中的break或continue語句也可能使控制權進入finally代碼塊。



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM