ClassNotFoundException和NoClassDefError之間的區別是什麼?

常見的異常(Exception)及錯誤(Error)分類

在這裏插入圖片描述
可以發現
1)ClassNotFoundException爲非RuntimeException(CheckedException),也就是說該異常在程序編譯前就會檢查出該錯誤,導致無法通過編譯,逼迫程序員修改代碼。所以這裏的ClassNotFoundException應該指的是找不到所定義的Class的代碼段。
2)NoClassDefError並不是發生在編譯前,而是編譯後的運行期間(通常在jvm類加載過程),通常分以下三種成因:
①加載該類時發現找不到該類的.class文件或者該類的jar包不存在;
②類的.class文件存在,但是在不同的域中。比如說,.class在當前的java path下不可用又或者說有多個不同的類加載器重複對該類的.class文件進行了加載,就有可能出現這樣的問題;
③大小寫問題,因爲在編譯時,雖然類名可能大小寫不同,但如果字母都一樣,那麼最後不管類名大小寫是否相同,編譯後都只產生一個.class文件!這樣就會導致最後編譯出來的文件不是我們想要的。

這裏我對NoClassDefError的第三種成因做了實驗,來幫助大家更好的理解。

在這裏插入圖片描述
如上圖,我已經創建了一個類名爲ErrorAndException的類,但是,當我試圖在該包下創建一個全小寫的類(其類名爲errorandexception)時,IDEA會阻止我創建並提示我該類已經存在,這說明了類名大小寫確實無視,只是我們平時規範了大小寫而已。
在這裏插入圖片描述
再如上圖,我繼續在該類下創建了兩個非public類,類名分別爲 AaAaaa,來查看其字節碼進行分析。但是當我編譯後,在output文件夾下生成的字節碼文件只有aaa.classs並未生成AaA.class文件,這也進一步說明類的大小寫不影響。
利用javap -v aaa.class查看其字節碼如下:
在這裏插入圖片描述
這個aaa.class字節碼居然實際存放的是AaA類!這就是說的大小寫導致得到的.class裏面加載的類並不是實際想要加載的類,而報NoClassDefError

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