为什么引发异常会尝试加载类(尽管它不会执行),而不是常规类

时间:2019-02-21 14:10:29

标签: java java-8 jvm-hotspot

我有以下课程。

我已经使用 javac 手动编译了这些类,并运行了Driver类。

后来删除entity.classMyCustomException.class,并按如下所示运行了该应用程序。

  

java驱动程序测试

抱怨以下错误是因为缺少MyCustomException,而不是关于Entity类。因此,不清楚为什么JRE抱怨MyCustomException类,而不抱怨Entity类。

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

Caused by: java.lang.NoClassDefFoundError: com/techdisqus/exception/MyCustomException

请注意,当我将命令参数传递为 test <时, IF 条件将不执行 / p>

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

MyCustomException.java

public class MyCustomException extends RuntimeException {

}

Entity.java

public class Entity {
}

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");
        }
    }
}

enter image description here

感谢帮助

2 个答案:

答案 0 :(得分:9)

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

我假设错误发生在verification期间,当时已加载的类经过了一些健全性检查,因此运行时可以稍后进行一些假设。

检查之一是字节码指令的类型检查。具体是athrow

  

如果操作数堆栈的顶部与Throwable相匹配,则一条throw指令为safe类型。

因此,此时,类加载器必须加载MyCustomException以检查其是否扩展了Throwable

答案 1 :(得分:-3)

我已经运行了您的代码。一切正常。加载“常规”类和Exception类的子类之间有区别。您遇到的问题是因为您仅编译了一个类(从共享的映像中)。另外两个类(Entity和MyCustomException)没有.class文件。

通过以下方式编译两个类:

cd src
javac ./package_folder/* //where package_folder is the package folder containing your classes

之后,使用以下命令运行类:

java package_folder.Driver test

查看图片中的结果文件: enter image description here

希望这会有所帮助!