【发布时间】:2013-03-23 04:38:51
【问题描述】:
当我运行此代码时,应用程序以 ClassNotFoundException 退出:
//uncaught ClassNotFoundException
try
{
Class<?> clazz = defineClass(null, bytes, 0, bytes.length, null);
table.put(clazz.getName(), clazz);
}
catch (NoClassDefFoundError e)
{
}
当我尝试编译此代码时,编译器抱怨 ClassNotFoundException 不可访问,因为它不是从 try-catch 语句的 try 子句中抛出的。
//Won't compile
try
{
Class<?> clazz = defineClass(null, bytes, 0, bytes.length, null);
table.put(clazz.getName(), clazz);
}
catch (ClassNotFoundException e)
{
}
当我运行这段代码时,唯一被捕获的是 NoClassDefFoundError。
//catches throwable of type java.lang.NoClassDefFoundError,
//with a java.lang.ClassNotFoundException as its cause
try
{
Class<?> clazz = defineClass(null, bytes, 0, bytes.length, null);
table.put(clazz.getName(), clazz);
}
catch (Throwable e)
{
System.out.println(e.getClass().getName());
System.out.println(e.getCause().getClass().getName());
}
下面的代码将编译并捕获错误(并且只有错误),但它很笨拙:
//possible workaround
try
{
Class<?> clazz = defineClass(null, bytes, 0, bytes.length, null);
table.put(clazz.getName(), clazz);
if (1 == 0) throw new ClassNotFoundException(); // we want the code to compile
}
catch (ClassNotFoundException e)
{
System.out.println("ex");
}
catch (NoClassDefFoundError e)
{
System.out.println("err");
}
然而,当我编写以下内容时,我可以在没有 catch 子句的情况下解决错误原因:
//and yet this works just fine...
try
{
throw new Error(new IOException());
}
catch (Error e)
{
System.out.println("err");
}
示例 3 会让我得出结论,throwable 是 NoClassDefFoundError。 示例 1 会让我得出结论,throwable 是 ClassNotFoundException。 然而,示例 2 表明 java 甚至不允许我编写代码来正确捕获 ClassNotFoundException。
就在我即将断定这里的问题是异常引起的错误时,我运行了前面示例中显示的代码,这表明这不是规则。
有人可以解释一下这里发生了什么吗?
PS:这是堆栈跟踪:
java.lang.NoClassDefFoundError: com/my/pckage/MyClass
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:791)
at Main$MyClassLoader.getClasses(Main.java:78)
at Main.main(Main.java:109)
Caused by: java.lang.ClassNotFoundException: com.my.pckage.MyClass
at java.lang.ClassLoader.findClass(ClassLoader.java:522)
at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
... 4 more
【问题讨论】:
-
有些东西没有加起来。假设您正在编写自定义类加载器,请包含您可能为它定义的任何覆盖方法。
-
defineClass不会抛出 ClassNotFoundException。如果您遇到该异常,则它来自其他地方。 -
@j-smith 如果你能提供一个 sscce 来显示问题,那就更好了。无与伦比的异常有相当多的可能性。例如,导致应用程序退出的“最终”异常可能是由某个外部级别抛出的,它会捕获您的 NoClassDefFoundError 并使用 ClassNotFoundException 重新抛出。如果您可以检查异常的“原因”以及异常中的调用堆栈,那就更好了。它让您了解异常的实际来源。
-
@AdrianShum 如果捕捉到
Exception,然后获取异常的堆栈跟踪,这是一个完全可行的解决方案。 -
@syb0rg 用于调试,否则您实际上并没有解决任何问题。
标签: java exception error-handling throwable