ClassNotFoundException is an Exception that occurs when a Class is dynamically loaded using a method like class.forname () because the corresponding Class was not found.
NoClassDefFoundError is an Error, indicating that a class exists at compile time and the class file is not found at runtime.
A, a ClassNotFoundException
In a typical trigger scenario, the load fails when the following methods are called:
- Class.forName(),
- ClassLoader.loadClass()
- ClassLoader.findSystemClass()
- Class initialization via reflection mechanism
For example, when loading database driver:
public class ExceptionTest {
public static void main(String[] args)throws Exception {
Class.forName("oracle.jdbc.driver.OracleDriver"); }}Copy the code
Second, the NoClassDefFoundError
Typical triggering scenarios are as follows:
1. A class exists at compile time but is not found at run time
public class A {
public void hello(a){
System.out.println("hello, world."); }}class B {
public static void main(String[] args) {
A a = newA(); }}Copy the code
The Java class above is compiled to generate two class files, one a.class and one B.class.
Now when I compile, I delete A’s class file and execute B’s main method, which raises A NoClassDefFoundError, because when I get to A A =new A(), The JVM assumes that this class must be in the current classpath, otherwise the compilation will not pass.
If it does exist, it must be found in the JVM. If it cannot be found, something is wrong.
2. If a class fails to be initialized, other classes invoke this class, causing execution failure
Class that failed to initialize:
public class InitFail {
static double divideZero = 1/0;// Class initialization fails on purpose.
public static void print(a){
System.out.println("123"); }}Copy the code
Call as follows:
public static void main(String[] args) {
try {
double divideZero = InitFail.divideZero;
}catch (Throwable e){
// Here, Throwable must be used, Exception will exit directly.
System.out.println(e);
}
// Continue to use.
InitFail.print();
}
Copy the code
This is a special case, not because the compile-time and run-time environments are inconsistent, but for a class that continues to be used even after initialization fails.
The JVM will assume that this is abnormal, and since its first call failed, the JVM will assume that subsequent calls will still fail, so it simply throws an ERROR to the client.
Third, summary
To summarize, here’s a chart:
Reference article:
Segmentfault.com/a/119000002…