ClassNotFoundException和NoClassDefFoundError的區別

原文地址:http://my.oschina.net/jasonultimate/blog/166932


正如它們的名字所說明的:NoClassDefFoundError是一個錯誤(Error),而ClassNOtFoundException是一個異常,在Java中錯誤和異常是有區別的,我們可以從異常中恢復程序但卻不應該嘗試從錯誤中恢復程序。

ClassNotFoundException的產生原因:

Java支持使用Class.forName方法來動態地加載類,任意一個類的類名如果被作爲參數傳遞給這個方法都將導致該類被加載到JVM內存中,如果這個類在類路徑中沒有被找到,那麼此時就會在運行時拋出ClassNotFoundException異常

要解決這個問題很容易,唯一需要做的就是要確保所需的類連同它依賴的包存在於類路徑中。當Class.forName被調用的時候,類加載器會查找類路徑中的類,如果找到了那麼這個類就會被成功加載,如果沒找到,那麼就會拋出ClassNotFountException,除了Class.forName,ClassLoader.loadClass、ClassLOader.findSystemClass在動態加載類到內存中的時候也可能會拋出這個異常。

另外還有一個導致ClassNotFoundException的原因就是:當一個類已經某個類加載器加載到內存中了,此時另一個類加載器又嘗試着動態地從同一個包中加載這個類。

由於類的動態加載在某種程度上是被開發者所控制的,所以他可以選擇catch這個異常然後採取相應的補救措施。有些程序可能希望忽略這個異常而採取其他方法。還有一些程序則會終止程序然後讓用戶再次嘗試前做點事情。

NoClassDefFoundError產生的原因:

如果JVM或者ClassLoader實例嘗試加載(可以通過正常的方法調用,也可能是使用new來創建新的對象)類的時候卻找不到類的定義。要查找的類在編譯的時候是存在的,運行的時候卻找不到了。這個錯誤往往是你使用new操作符來創建一個新的對象但卻找不到該對象對應的類。這個時候就會導致NoClassDefFoundError.

由於NoClassDefFoundError是有JVM引起的,所以不應該嘗試捕捉這個錯誤。

解決這個問題的辦法就是:查找那些在開發期間存在於類路徑下但在運行期間卻不在類路徑下的類

另:

ClassNotFoundException發生在裝入階段。 
當應用程序試圖通過類的字符串名稱,使用常規的三種方法裝入類,但卻找不到指定名稱的類定義時就拋出該異常。

NoClassDefFoundError: 當目前執行的類已經編譯,但是找不到它的定義時

也就是說你如果編譯了一個類B,在類A中調用,編譯完成以後,你又刪除掉B,運行A的時候那麼就會出現這個錯誤

加載時從外存儲器找不到需要的class就出現ClassNotFoundException 
連接時從內存找不到需要的class就出現NoClassDefFoundError

另:


NoClassDefFoundError 解決的三種方法:

1. Simple example of NoClassDefFoundError is class belongs to a jar and jar was not added into classpath or sometime jar’s name has been changed by someone like in my case one of my colleague has changed tibco.jar into tibco_v3.jar and by program is failing with java.lang.NoClassDefFoundError and I was wondering what’s wrong.

首先是類在運行的時候依賴於其它的一個jar包,但是該jar包沒有加載到classpath中或者是該jar包的名字被其他人改了,就像我的一個例子tibo.jar改爲了tibco_v3.jar…….

2. Class is not in Classpath, there is no sure shot way of knowing it but many a times you can just have a look to print System.getproperty(”java.classpath“)and it will print the classpath from there you can at least get an idea of your actual runtime classpath.

運行的類不在classpath中,這個問題沒有一個確定的方法去知道,但是很多時候你可以通過System.getproperty(”java.classpath“)方法,該方法能讓你至少可以領略到實際存在的運行期間的classpath。

 
3. Just try to run with explicitly -classpath option with the classpath you think will work and if its working then it’s sure short sign that some one is overriding java classpath.

試着通過-classpath命令明確指出你認爲正確的classpath,如果能夠正常執行的話就說明你使用的classpath是正確的,而系統中的classpath已經被修該過了。


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