一、Error和Exception什么关系
Error和Exception都继承自Throwable。继承关系如下图所示:
其实Error和Exception就是java语言设计Throwable时的两个大的分类:Error一般是比较严重的问题,不应该被catch,比如出现了OutOfMemoryError,StackOverFlowError这些错误,程序员是无能为力的;而Exception是程序员可以干预的,可以被catch。看下java源码的注释。
1. Error
/**
* An {@code Error} is a subclass of {@code Throwable}
* that indicates serious problems that a reasonable application
* should not try to catch. Most such errors are abnormal conditions.
* The {@code ThreadDeath} error, though a "normal" condition,
* is also a subclass of {@code Error} because most applications
* should not try to catch it.
* <p>
* A method is not required to declare in its {@code throws}
* clause any subclasses of {@code Error} that might be thrown
* during the execution of the method but not caught, since these
* errors are abnormal conditions that should never occur.
*
* That is, {@code Error} and its subclasses are regarded as unchecked
* exceptions for the purposes of compile-time checking of exceptions.
*
* @author Frank Yellin
* @see java.lang.ThreadDeath
* @jls 11.2 Compile-Time Checking of Exceptions
* @since 1.0
*/
public class Error extends Throwable
Error就是一个比较严重的问题,不应该被catch;它是一个unchecked exception,也就是说,不需要在方法上声明throws,它不是一个编译器可以发现的checked exception。
2. Exception
/**
* The class {@code Exception} and its subclasses are a form of
* {@code Throwable} that indicates conditions that a reasonable
* application might want to catch.
*
* <p>The class {@code Exception} and any subclasses that are not also
* subclasses of {@link RuntimeException} are <em>checked
* exceptions</em>. Checked exceptions need to be declared in a
* method or constructor's {@code throws} clause if they can be thrown
* by the execution of the method or constructor and propagate outside
* the method or constructor boundary.
*
* @author Frank Yellin
* @see java.lang.Error
* @jls 11.2 Compile-Time Checking of Exceptions
* @since 1.0
*/
public class Exception extends Throwable
Exception及其子类是可以被catch处理的。Exception及其子类(不包括RuntimeException及其子类)都是checked exception,可以被编译器发现。也就是说,如果不显示处理这些checked exception,编译无法通过。怎么处理呢?可以在方法或者构造方法上声明throws,或者增加try catch语句块。
写到这里,除了checked exception,其他都是unchecked exception。所谓checked是针对编译器而言的,只有编译器会“检查”;运行时异常和Error显然是编译器无法“检查”到的。
二、NoClassDefFoundError 和 ClassNotFoundException
这两个有什么区别。从字面上就可以看到,一个是Error,一个是Exception。看下java定义:
1. ClassNotFoundException
/**
* Thrown when an application tries to load in a class through its
* string name using:
* <ul>
* <li>The <code>forName</code> method in class <code>Class</code>.
* <li>The <code>findSystemClass</code> method in class
* <code>ClassLoader</code> .
* <li>The <code>loadClass</code> method in class <code>ClassLoader</code>.
* </ul>
* <p>
* but no definition for the class with the specified name could be found.
*
*
* @author unascribed
* @see java.lang.Class#forName(java.lang.String)
* @see java.lang.ClassLoader#findSystemClass(java.lang.String)
* @see java.lang.ClassLoader#loadClass(java.lang.String, boolean)
* @since 1.0
*/
public class ClassNotFoundException extends ReflectiveOperationException
可以看到,它是个反射操作异常,并不是一个RuntimeException,也就是它是一个checked exception,必须显示的throws或者try catch,否则无法编译通过。
2. NoClassDefFoundError
/**
* Thrown if the Java Virtual Machine or a <code>ClassLoader</code> instance
* tries to load in the definition of a class (as part of a normal method call
* or as part of creating a new instance using the <code>new</code> expression)
* and no definition of the class could be found.
* <p>
* The searched-for class definition existed when the currently
* executing class was compiled, but the definition can no longer be
* found.
*
* @author unascribed
* @since 1.0
*/
public
class NoClassDefFoundError extends LinkageError
NoClassDefFoundError是当new这个类的实例的时候,在JVM中找不到这个类的定义。也就是,这个类在编译的时候还是在的,都已经装载到JVM中了,但是在new实例的时候却不存在了,真是匪夷所思。
三、参考链接
- Checked and unchecked exceptions in java with examples
- 看完这篇Exception 和 Error,和面试官扯皮就没问题了
- ClassNotFoundException 和 NoClassDefFoundError 的区别
硬广告
欢迎关注公众号:double6