Когда я запускаю этот код, приложение выходит из ClassNotFoundException:
//uncaught ClassNotFoundException
try
{
Class<?> clazz = defineClass(null, bytes, 0, bytes.length, null);
table.put(clazz.getName(), clazz);
}
catch (NoClassDefFoundError e)
{
}
Когда я пытаюсь скомпилировать этот код, компилятор жалуется, что исключение ClassNotFoundException недоступно, потому что оно не выбрано из try-предложения инструкции try-catch.
//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