在Java中,异常类在编译时是如何链接的

在Java中,异常类在编译时是如何链接的,java,unit-testing,exception-handling,testng,Java,Unit Testing,Exception Handling,Testng,作为Java面向对象编程入门的一部分,我们进行了一个20-36小时的大型实践练习——今年是基于俄罗斯方块的。学生们遵循指南,通过文本描述和uml类图解释如何实现他们的游戏。与本指南相连的是一个工具,它运行一套使用TestNg编写的单元测试,以检查它们的实现是否符合说明。单元测试是使用100%一致版本的代码预编译的,并通过显示测试结果的自定义用户界面启动。执行的测试数量取决于学生达到的部分 单元测试类的结构都类似: public static void classExists(String ful

作为Java面向对象编程入门的一部分,我们进行了一个20-36小时的大型实践练习——今年是基于俄罗斯方块的。学生们遵循指南,通过文本描述和uml类图解释如何实现他们的游戏。与本指南相连的是一个工具,它运行一套使用TestNg编写的单元测试,以检查它们的实现是否符合说明。单元测试是使用100%一致版本的代码预编译的,并通过显示测试结果的自定义用户界面启动。执行的测试数量取决于学生达到的部分

单元测试类的结构都类似:

public static void classExists(String fullClassName) {
    try {
        @SuppressWarnings("unused")
        Class<?> clazz = Class.forName(fullClassName);
    } catch (ClassNotFoundException cnfe) {
        fail(fullClassName + " could not be found on the classpath.");
    }
}
测试按预期工作,特别是在BloxexException不存在、测试1失败且其他测试未执行的情况下,但是如果我们尝试引发异常:

throw new BloxException("Message", value);
测试不会执行,因为TestNg找不到类BloxexException。 我们假设这是由于Java如何编译上面的两行代码,有人能告诉我为什么在抛出异常时我们需要类,但是如果我们创建一个新的异常,我们不需要代码来执行测试吗

以下是仅在使用throw new BloxexException时发生的异常StackTrace:

java.lang.NoClassDefFoundError: fr/eseo/blox/model/BloxException
at java.lang.Class.getDeclaredMethods0(Native Method)
at java.lang.Class.privateGetDeclaredMethods(Class.java:2436)
at java.lang.Class.privateGetPublicMethods(Class.java:2556)
at java.lang.Class.getMethods(Class.java:1412)
at org.testng.internal.TestNGClassFinder.<init>(TestNGClassFinder.java:59)
at org.testng.TestRunner.initMethods(TestRunner.java:409)
at org.testng.TestRunner.init(TestRunner.java:235)
at org.testng.TestRunner.init(TestRunner.java:205)
at org.testng.TestRunner.<init>(TestRunner.java:153)
at org.testng.SuiteRunner$DefaultTestRunnerFactory.newTestRunner(SuiteRunner.java:522)
at org.testng.SuiteRunner.init(SuiteRunner.java:157)
at org.testng.SuiteRunner.<init>(SuiteRunner.java:111)
at org.testng.TestNG.createSuiteRunner(TestNG.java:1273)
at org.testng.TestNG.createSuiteRunners(TestNG.java:1260)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1114)
at org.testng.TestNG.run(TestNG.java:1031)
at fr.eseo.ac20.core.validation.runners.Validator.<init>(Validator.java:131)
at fr.eseo.ac20.core.validation.runners.CustomValidator.<init>(CustomValidator.java:21)
at fr.eseo.ac20.core.validation.runners.CustomValidator.main(CustomValidator.java:17)
Caused by: java.lang.ClassNotFoundException: fr.eseo.blox.model.BloxException
    at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
    ... 19 more
然后切换到tng_bad文件夹并执行相同的操作

java -cp testng-6.0.1.jar:. org.testng.TestNG tng.xml

第一个执行,当exists测试失败时,第二个给出异常。测试方法的代码源在示例子文件夹中,这与异常无关。这里的问题在于加载代码的方式

在第一种情况下,你打电话

Class.forName(fullClassName);
在一个不可用的类上,您将得到一个ClassNotFoundException,并且该类将不会被加载

在第二种情况下,TestNG TestRunner类加载了一个依赖于另一个不可用的类的类。然后过了一会儿,它试图获取一个方法的类型信息。。。这是失败的,因为缺少依赖关系。由于JVM现在已经通知应用程序一个缺少依赖项的类,因此它现在处于该类被破坏的状态。因此,它会抛出不同的异常NoClassDefFoundError

基本上,独立加载和测试类的想法是行不通的。加载类时,它所依赖的任何类(包括它抛出的任何异常)都需要可用于加载。。。否则你会得到例外

他们不应该运行它,但作为学生,他们有时会尝试运行所有的测试,即使他们没有完成该部分


简单。向他们解释,如果他们那样做,它将不起作用:-

这几乎没有意义。无论您是否抛出异常,您都有完全相同的实例创建表达式,无论上下文如何,其计算结果都完全相同。向我们展示TestNg中的堆栈跟踪,显示您正在谈论的行为。我认为这不是异常的特殊之处。你确定类文件在正确的位置,并且在需要的地方正确键入了名称吗?Marko,我完全同意你的观点,但是当我尝试抛出一个新异常时,我从TestNg和我的runner类中得到一个异常,该类不存在,但是当我只是实例化该类时,我的第一个测试被执行,它停止测试并跳过最后的测试。如果他们没有类,你希望他们如何运行它?我想同意你的看法,但我现在通过链接添加了一个示例。请参阅我编辑的第一篇文章,一个测试按预期执行,类。forName。。。正确地说类不存在,但是当抛出异常时,测试将不会执行。
java -cp testng-6.0.1.jar:. org.testng.TestNG tng.xml
Class.forName(fullClassName);