在你捕获一个异常之前,肯定在某个地方有代码抛出了这个异常。任何代码都可以抛异常:你的代码,别人写的代码包(比如Java平台里面的代码包),或者Java运行时系统。不管是什么抛出异常,总是用throw语句来抛出的。

你可能已经注意到了,Java平台提供了大量的异常类。所有这些异常类都是 Throwable 类的子类,并且可以让程序区分在程序执行过程中可能发生的不同种类的异常。

你可以创建你自己的异常类,来代表你写的类中可能会出现的问题。事实上,如果你是一个代码包开发者,你可能必须创建自己的一套异常类型,让用户可以区分错误是发生在你的包还是Java平台或者其他的包。

你也可以创建链式异常(chained exception),可以看 Chained Exceptions 章节了解更多信息。

throw语句

所有方法都是用throw语句抛异常。throw语句要求要有一个单独参数:一个Throwable对象。Throwable对象可以是Throwable类的任何子类的实例。这里有一个throw语句的例子:

throw someThrowableObject;

让我们看看在上下文中的throw语句。下面的pop方法是在一个实现了普通堆栈功能的类里面的方法。这个方法把堆栈的顶部元素移除,并返回给用户。

public Object pop() {
    Object obj;

    if (size == 0) {
        throw new EmptyStackException();
    }

    obj = objectAt(size - 1);
    setObjectAt(size - 1, null);
    size--;
    return obj;
}

pop会首先检查是否有元素在堆栈里面。如果堆栈是空的(size为0),pop就会初始化一个EmptyStackException对象(java.util的一个成员)并抛出。在 Creating Exception Classes 章节介绍了怎么创建你自己的异常类型。现在你只要记住,你可以抛出任何继承了java.lang.Throwable类的对象。

注意pop方法的声明部分并没有包含throws从句。因为EmptyStackException是一个非检查异常,所以pop没必要描述它可能会发生。

Throwable类及其子类

继承Throwable类的对象包括直接继承(继承Throwable类)和间接继承(继承Throwable类的子孙类)。下图描述了Throwable类及其重要子类组成的层级关系。如你所见,Throwable有两个直接继承者: Error 和 Exception

Throwable类



Error类

当Java虚拟机中发生一个动态链接失败或者其他硬故障,虚拟机就会抛出一个Error。简单的程序通常不会捕获或抛出Error。

Exception类

大部分程序抛出和捕获的对象都是继承于Exception类。一个Exception表明有一个问题发生了,但不是严重的系统问题,你写的大多数程序都将是抛出和捕获Exception,而不是Error。

Java平台定义了大量的Exception类的继承者。这些继承者说明有很多不同种类的异常可能会发生。例如,IllegalAccessException指示了找不到某个方法,NegativeArraySizeException指示了程序企图用负size创建数组。

Exception的子类之一,RuntimeException,用于保留那些“指示API使用错误 ”的Exception。运行时异常的一个例子就是NullPointerException,当一个方法试图访问一个对象的成员,而这个对象的引用是null的时候,就会发生NullPointerException异常。 Unchecked Exceptions — The Controversy  讨论了为什么大多数程序不应该抛出运行时异常或运行时异常的子类。





原文地址