Java中基本的类装入异常(转载)

Java中基本的类装入异常
在java中,类装载异常虽然不是很常见,可如果发生异常,其处理还是比较麻烦的。

下面的几种异常是比较常见的:

ClassNotFoundException

ClassNotFoundException 是最常见的类装入异常类型。它发生在装入阶段。Java 规范对 ClassNotFoundException 的描述是这样的:

当应用程序试图通过类的字符串名称,使用以下三种方法装入类,但却找不到指定名称的类定义时抛出该异常。

* 类 Class 中的 forName() 方法。

* 类 ClassLoader 中的 findSystemClass() 方法。

* 类 ClassLoader 中的 loadClass() 方法。

所以,如果显式地装入类的尝试失败,那么就抛出 ClassNotFoundException。

这些异常修复起来通常比较简单。可以用 verbose 选项检查类路径,确保使用的类路径设置正确。如果类路径设置正确,但是仍然看到这个错误,那么就是需要的类在类路径中不存在。要修复这个问题,可以把类移动到类路径中指定的目录或 JAR 文件中,或者把类所在奈恢锰砑拥嚼嗦肪吨小?br>


NoClassDefFoundError

NoClassDefFoundError 是类装入器在装入阶段抛出的另一个常见异常。JVM 规范对 NoClassDefFoundError 的定义如下:

如果 Java 虚拟机或 ClassLoader 实例试图装入类定义(作为正常的方法调用的一部分,或者作为使用 new 表达式创建新实例的一部分),但却没有找到类定义时抛出该异常。

当目前执行的类已经编译,但是找不到它的定义时,会存在 searched-for 类定义。

实际上,这意味着 NoClassDefFoundError 的抛出,是不成功的隐式类装入的结果。

简单说来,就是引用的类在类路径中没有找到。

ClassCastException

类装入器能够抛出的另一个异常是 ClassCastException。它是在类型比较中发现不兼容类型的时候抛出的。JVM 规范指定 ClassCastException 是:

该异常的抛出,表明代码企图把对象的类型转换成一个子类,而该对象并不是这个子类的实例。

UnsatisfiedLinkError

在把本地方法调用链接到对应的本机定义时,类装入器扮演着重要角色。如果程序试图装入一个不存在或者放错的本机库时,在链接阶段的解析过程会发生 UnsatisfiedLinkError。JVM 规范指定 UnsatisfiedLinkError 是:

对于声明为 native 的方法,如果 Java 虚拟机找不到和它对应的本机语言定义,就会抛出该异常。

当调用本机方法时,类装入器会尝试装入定义了该方法的本机库。如果找不到这个库,就会抛出这个错误。

本机库的装入由调用 System.loadLibrary() 方法的类的类装入器启动,根据使用的类装入器,会搜索不同的位置:

* 对于由 bootstrap 类装入器装入的类,搜索 sun.boot.library.path。

* 对于由扩展类装入器装入的类,先搜索 java.ext.dirs,然后是 sun.boot.library.path,然后是 java.library.path。

* 对于由系统类装入器装入的类,搜索 sun.boot.library.path,然后是 java.library.path。

ClassCircularityError

JVM 规范指定 ClassCircularityError 的抛出条件是:

类或接口由于是自己的超类或超接口而不能被装入。

这个错误是在链接阶段的解析过程中抛出的。这个错误有点奇怪,因为 Java 编译器不允许发生这种循环情况。但是,如果独立地编译类,然后再把它们放在一起,就可能发生这个错误。

ClassFormatError

JVM 规范指出,抛出 ClassFormatError 的条件是:

负责指定所请求的编译类或接口的二进制数据形式有误。

这个异常是在类装入的链接阶段的校验过程中抛出。如果字节码发生了更改,例如主版本号或次版本号发生了更改,那么二进制数据的形式就会有误。例如,如果对字节码故意做了更改,或者在通过网络传送类文件时现出了错误,那么就可能发生这个异常。

修复这个问题的惟一方法就是获得字节码的正确副本,可能需要重新进行编译。

ExceptionInInitializerError

根据 JVM 规范,抛出 ExceptionInInitializer 的情况是:

* 如果初始化器突然完成,抛出一些异常 E,而且 E 的类不是 Error 或者它的某个子类,那么就会创建 ExceptionInInitializerError 类的一个新实例,并用 E 作为参数,用这个实例代替 E。

* 如果 Java 虚拟机试图创建类 ExceptionInInitializerError 的新实例,但是因为出现 Out-Of-Memory-Error 而无法创建新实例,那么就抛出 OutOfMemoryError 对象作为代替。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值