为什么抛出异常会尝试加载类(虽然它没有执行)但不是常规类

sec*_*tar 9 java jvm-hotspot java-8

我有以下课程.

我已经使用javac手动编译了类并运行了Driver该类.

后来删除entity.classMyCustomException.class运行应用程序,如下所示.

java驱动程序测试

以下错误被抱怨MyCustomException丢失但不是关于Entity班级.所以,不清楚为什么JRE抱怨MyCustomException课而不是Entity课.

确实我已经删除了代码,throw new MyCustomException();但我没有遇到关于Entity类的错误.

Caused by: java.lang.NoClassDefFoundError: com/techdisqus/exception/MyCustomException
Run Code Online (Sandbox Code Playgroud)

请注意,IF条件不会执行,因为我将命令参数作为测试传递

为什么抛出异常会导致加载MyCustomException永远不会执行的异常,但除非条件满足,否则JVM不会加载任何其他常规类,如此处的Entity类所示.请检查Driver.java下面.

MyCustomException.java

public class MyCustomException extends RuntimeException {

}
Run Code Online (Sandbox Code Playgroud)

Entity.java

public class Entity {
}
Run Code Online (Sandbox Code Playgroud)

Driver.java

public class Driver {


    public static void main(String[] args) {

        String s = args[0];
        if("true".equals(s)){
            Entity entity = new Entity(); // This is not loaded, unless s is true
            throw  new MyCustomException(); // this is loaded even s is NOT true.
        }else{
            System.out.println("success");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

感谢帮助

Ohl*_*leC 9

(这是一个有根据的猜测;我绝不是JVM内部的专家)

我假设在验证期间发生错误,当加载的类经过一些健全性检查时,运行时可以稍后做出一些假设.

其中一项检查是字节码指令的类型检查.特别是athrow:

如果操作数堆栈的顶部与Throwable匹配,则athrow指令是类型安全的.

所以在这一点上,类加载器必须加载MyCustomException以检查它是否扩展Throwable

  • 关于验证点有一些自由.HotSpot JVM在尝试输入`main`方法时会这样做,但是在初始化包含`Driver`类时,或者在实际尝试执行`athrow`指令之前,它也可以更早地执行它.另一方面,仅在实际尝试执行`new`指令之前才检测到`Entity`类的缺失,但是另一个实现可以在方法入口或甚至类初始化时检查它. (3认同)
  • 究竟.但重要的是要记住,这是一个特定于实现的行为,其他JVM可能会以不同的方式处理这种情况. (2认同)