Java 教程是为 JDK 8 编写的。本页中描述的示例和实践未利用在后续版本中引入的改进。
在捕获异常之前,某些代码必须抛出一个异常。任何代码都可以抛出异常:你的代码,来自其他人编写的包中的代码,例如 Java 平台附带的包或 Java 运行时环境。无论什么抛出异常,它总是使用 throw
语句抛出。
你可能已经注意到,Java 平台提供了许多异常类。所有类都是 Throwable
类的后代,并且所有类都允许程序区分在程序执行期间可能发生的各种异常的类型。
你还可以创建自己的异常类来表示你编写的类中可能出现的问题。实际上,如果你是程序包开发人员,则可能必须创建自己的一组异常类,以允许用户将程序包中可能发生的错误与 Java 平台或其他程序包中发生的错误区分开来。
你还可以创建 chained (链式) 异常。有关更多信息,请参见 Chained Exceptions 部分。
所有方法都使用 throw
语句来抛出异常。throw
语句需要一个参数:一个 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
方法检查堆栈上是否有任何元素。如果堆栈为空(其大小等于 0
),则 pop
实例化一个新的 EmptyStackException
对象(java.util
的成员)并抛出它。本章中的 Creating Exception Classes 部分介绍了如何创建自己的异常类。现在,你需要记住的是,你只能抛出从 java.lang.Throwable
类继承的对象。
请注意,pop
方法的声明不包含 throws
子句。EmptyStackException
不是检查型异常,因此不需要 pop
来声明它可能发生。
从 Throwable
类继承的对象包括直接后代(直接从 Throwable
类继承的对象)和间接后代(从 Throwable
的子类或孙子类继承的对象)。下图说明了 Throwable
类的类层次结构及其最重要的子类。如你所见,Throwable
有两个直接后代:Error
和 Exception
。
Throwable 类。
当发生 Java 虚拟机中的动态链接故障或其他硬故障时,虚拟机将引发 Error
。简单程序通常 不 捕获或抛出 Error
。
大多数程序抛出和捕获从 Exception
类派生的对象。Exception
表示发生了问题,但这不是一个严重的系统问题。你编写的大多数程序将抛出和捕获 Exception
,而不是 Error
。
Java 平台定义了 Exception
类的许多后代。这些后代表示可能发生的各种异常的类型。例如,IllegalAccessException
表示无法找到特定方法,NegativeArraySizeException
表示程序试图创建负大小的数组。
一个 Exception
子类 RuntimeException
保留用于指示不正确使用 API 的异常。运行时异常的一个示例是 NullPointerException
,当方法尝试通过 null
引用访问对象的成员时发生。部分 Unchecked Exceptions The Controversy 讨论了为什么大多数应用程序不应抛出运行时异常 RuntimeException
或其子类 。