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:

  1. Class.forName(),
  2. ClassLoader.loadClass()
  3. ClassLoader.findSystemClass()
  4. 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…