ClassNotFoundException and NoClassDefFoundError both signal a missing class, but they differ in cause and timing. ClassNotFoundException is a checked exception thrown when code explicitly tries to load a class by name, such as with Class.forName(), and the classpath doesn't contain it, while NoClassDefFoundError is an unchecked error thrown when a class that was available at compile time can no longer be found or failed to initialize at runtime.
Key Points: • ClassNotFoundException happens during explicit, dynamic class loading, for example a JDBC driver name that's misspelled or missing from the classpath when calling Class.forName(). • NoClassDefFoundError happens when the compiler saw the class and compiled successfully against it, but the JVM can't locate or link it at runtime, often due to a classpath change after compilation. • NoClassDefFoundError can also occur if the class's static initializer threw an exception the first time it was loaded, leaving the class in a permanently unusable state for the rest of the JVM's life. • ClassNotFoundException extends Exception and is checked, while NoClassDefFoundError extends Error, signaling a more severe, typically unrecoverable JVM-level linkage problem. • Fixing ClassNotFoundException usually means correcting the classpath or dependency; fixing NoClassDefFoundError often means tracing back to why static initialization failed the first time.
Example: Deploying a jar without one of its dependency jars on the classpath causes NoClassDefFoundError at runtime for a class the code compiled against successfully, whereas calling Class.forName with a typo in the class name throws ClassNotFoundException immediately.
Interview Tip: A concise interview answer is:
"ClassNotFoundException is a checked exception thrown when you explicitly try to load a class by name, like with Class.forName, and it isn't on the classpath. NoClassDefFoundError is an unchecked error thrown when a class that compiled fine can't be found or failed to initialize at runtime, often due to a classpath mismatch or a static initializer that threw an exception earlier."