常见的异常(Exception)及错误(Error)分类
可以发现
1)ClassNotFoundException为非RuntimeException(CheckedException),也就是说该异常在程序编译前就会检查出该错误,导致无法通过编译,逼迫程序员修改代码。所以这里的ClassNotFoundException应该指的是找不到所定义的Class的代码段。
2)NoClassDefError并不是发生在编译前,而是编译后的运行期间(通常在jvm类加载过程),通常分以下三种成因:
①加载该类时发现找不到该类的.class文件或者该类的jar包不存在;
②类的.class文件存在,但是在不同的域中。比如说,.class在当前的java path下不可用又或者说有多个不同的类加载器重复对该类的.class文件进行了加载,就有可能出现这样的问题;
③大小写问题,因为在编译时,虽然类名可能大小写不同,但如果字母都一样,那么最后不管类名大小写是否相同,编译后都只产生一个.class文件!这样就会导致最后编译出来的文件不是我们想要的。
这里我对NoClassDefError的第三种成因做了实验,来帮助大家更好的理解。
如上图,我已经创建了一个类名为ErrorAndException的类,但是,当我试图在该包下创建一个全小写的类(其类名为errorandexception)时,IDEA会阻止我创建并提示我该类已经存在,这说明了类名大小写确实无视,只是我们平时规范了大小写而已。
再如上图,我继续在该类下创建了两个非public类,类名分别为 AaA和aaa,来查看其字节码进行分析。但是当我编译后,在output文件夹下生成的字节码文件只有aaa.classs,并未生成AaA.class文件,这也进一步说明类的大小写不影响。
利用javap -v aaa.class查看其字节码如下:
这个aaa.class字节码居然实际存放的是AaA类!这就是说的大小写导致得到的.class里面加载的类并不是实际想要加载的类,而报NoClassDefError。