java基础:Error和Exception

1,099 阅读3分钟

一、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实例的时候却不存在了,真是匪夷所思。

三、参考链接

硬广告

欢迎关注公众号:double6