Java异常体系
一、异常体系
使用Java编程过程中,从编译时到运行时都可能会“出错”。这些出错信息我们一般通过异常处理或抛出异常进行解决。首先这些出错中包含异常Exception和错误Error。两者存在本质上的区别,异常是出现特殊情况,可以避免。错误是不可避免的,常常引起程序中断或终止。
异常发生的原因有很多,通常包含以下几大类:
- 用户输入了非法数据。
- 要打开的文件不存在。
而大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,当JVM内存溢出时,将出现 OutOfMemoryError。
Throwable
类是 Java 语言中所有错误或异常的超类。只有当对象是此类(或其子类之一)的实例时,才能通过 Java 虚拟机或者 Java throw
语句抛出。类似地,只有此类或其子类之一才可以是 catch
子句中的参数类型。Throwable 包含了其线程创建时线程执行堆栈的快照。它还包含了给出有关错误更多信息的消息字符串。最后,它还可以包含 cause(原因):另一个导致此 throwable 抛出的 throwable。此 cause 设施在 1.4 版本中首次出现。它也称为异常链 设施,因为 cause 自身也会有 cause,依此类推,就形成了异常链,每个异常都是由另一个异常引起的。
方法:
二、Error
Error
是 Throwable
的子类,用于指示合理的应用程序不应该试图捕获的严重问题。大多数这样的错误都是异常条件。虽然 ThreadDeath
错误是一个“正规”的条件,但它也是 Error
的子类,因为大多数应用程序都不应该试图捕获它。
在执行该方法期间,无需在其 throws
子句中声明可能抛出但是未能捕获的 Error
的任何子类,因为这些错误可能是再也不会发生的异常条件。
三、Exception
所有的异常类是从 java.lang.Exception 类继承的子类。Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。异常类有两个主要的子类:IOException 类和 RuntimeException 类。主要分为检查性异常和非检查性异常。
常见的非检查性异常:
常见的检查性异常:
四、捕获异常
1、try...catch关键字
使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。
try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下:
try { // 程序代码 }catch(ExceptionName e1) { //Catch 块 }
Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数到方法是一样。
一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。
多重捕获块的语法如下所示:
try{ // 程序代码 }catch(异常类型1 异常的变量名1){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }
2、throws/throw 关键字
如果一个方法没有捕获一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。也可以使用 throw 关键字抛出一个异常,无论它是新实例化的还是刚捕获到的。
下面方法的声明抛出一个 RemoteException 异常:
import java.io.*; public class className { public void deposit(double amount) throws RemoteException { // Method implementation throw new RemoteException(); } //Remainder of class definition }
一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。
3、finally关键字
finally 关键字用来创建在 try 代码块后面执行的代码块。无论是否发生异常,finally 代码块中的代码总会被执行。在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。
finally 代码块出现在 catch 代码块最后,语法如下:
try{ // 程序代码 }catch(异常类型1 异常的变量名1){ // 程序代码 }catch(异常类型2 异常的变量名2){ // 程序代码 }finally{ // 程序代码 }
4、自定义异常
在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。
- 所有异常都必须是 Throwable 的子类。
- 如果希望写一个检查性异常类,则需要继承 Exception 类。
- 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。
class MyException extends Exception{ }