ClassNotFoundException和NoClassDefFoundError的區(qū)別:
ClassNotFoundException:
- 它是Exception骗露,不是Error在Throwable體系中只是一個(gè)Exception,說(shuō)明它是可恢復(fù)的
- 發(fā)生的時(shí)機(jī)
- 當(dāng)應(yīng)用試圖通過(guò)給定的name加載對(duì)應(yīng)的class時(shí)可能拋出此異常渐夸,找不到對(duì)應(yīng)的class文件時(shí)拋出
- Class.forName(name);
- ClassLoader.findSystemClass();
- ClassLoader.loadClass();
- 當(dāng)應(yīng)用試圖通過(guò)給定的name加載對(duì)應(yīng)的class時(shí)可能拋出此異常渐夸,找不到對(duì)應(yīng)的class文件時(shí)拋出
NoClassDefFoundException
- Error級(jí)別坛掠,比Exception要嚴(yán)重
- JVM或者ClassLoader試圖加載一個(gè)class的definition的時(shí)候,找不到對(duì)應(yīng)的class的definition,通常時(shí)new A()的時(shí)候
因此,當(dāng)源文件編譯成功,但是運(yùn)行時(shí)找不到需要的class文件時(shí)从诲,會(huì)出現(xiàn)NoClassDefFoundError。這可能會(huì)發(fā)生在一個(gè)分布式或者生產(chǎn)的JAR中靡羡,里面沒(méi)有包含所有的需要的class文件盏求。
一個(gè)預(yù)期編譯時(shí)期沒(méi)問(wèn)題的程序在不能運(yùn)行可能是由于class文件找不到或者和編譯期生成或者面臨的不相同。這是一個(gè)非常嚴(yán)重的錯(cuò)誤亿眠,程序不能被JVM啟動(dòng)。
當(dāng)對(duì)應(yīng)的class文件不能被類(lèi)加載器找到的時(shí)候會(huì)拋出ClassNotFoundException,通常情況class在class path下找不到磅废,也有可能是這個(gè)class試圖被父類(lèi)加載器加載的一個(gè)class加載纳像,但是這個(gè)class只對(duì)子類(lèi)加載器可見(jiàn)。這種情況通常出現(xiàn)在比較復(fù)雜的環(huán)境中拯勉。
人們經(jīng)常搞混NoClassDefFoundError和ClassNotFoundExcepion,然后兩者大不相同竟趾。
java.lang.NoClassDefFoundError:
org/apache/activemq/ActiveMQConnectionFactory
這并不意味著ActiveMQConnectionFactory的class文件在classpath下找不到。實(shí)際上恰恰相反宫峦,這意味ActiveMQConnectionFactory的class是可以被類(lèi)加載器找到的岔帽,但是在試圖加載這個(gè)類(lèi)的時(shí)候,讀取class的definition時(shí)出現(xiàn)了錯(cuò)誤导绷。一般情況下當(dāng)class中有靜態(tài)代碼庫(kù)或者靜態(tài)字段時(shí)犀勒,而這些靜態(tài)代碼使用了當(dāng)前類(lèi)加載器找不到的class時(shí),會(huì)出現(xiàn)這樣的問(wèn)題。因此為了找到罪魁禍?zhǔn)准址眩榭磫?wèn)題中class的源碼钦购,找其中用到的靜態(tài)代碼塊和靜態(tài)字段,如果不能訪問(wèn)源碼褂萧,試圖反編譯它押桃。
代碼舉例,下面這行代碼导犹,確保SomeClass的class在classpath中唱凯。
private static SomeClass foo = new SomeClass();
代碼地址見(jiàn)此處