异常
Java语言中,程序执行中发生的不正常情况被称为“异常”。(开发过程中的语法错误和逻辑错误不是异常)
- Error: Java虚拟机无法解决的严重问题,严重错误,程序会崩溃。
- Exception:一般性问题,分为运行时异常与编译时异常。
异常体系图
- 异常分为两大类:运行时异常与编译时异常
- 运行时异常,编译器查不出来,一般指编程时的逻辑错误。这种异常很普遍,可以不做处理,尽量避免。
- 编译时异常是编译器要求必须处置的异常。
- Java 程序通常不捕获错误。错误一般发生在严重故障时,它们在Java程序处理的范畴之外。
常见运行时异常
- NullPointerException 空指针异常,如:程序需要调用的成员为null
- ArithmeticException 数学运算异常 ,如:除数为零
- ArrayIndexOutOfBoundsException 数组下标越界异常
- ClassCastException 类型转换异常,如:向下转型错误
- NumberFormatException 数字格式不正确异常[],如:当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式
常见编译时异常
- SQLException 操作数据库时,查询表出现异常
- IOException 操作文件时发生的异常
- FileNotFoundException 操作一个不存在的文件时 发生异常
- ClassNotFoundException 加载类 类不存在 异常
- EOFException 操作文件到文件末尾 发生异常
- IllegalArguementException 参数异常
异常处理机制
捕获异常(try-catch)
try{
// 程序代码(可能存在异常)
}catch(异常类型1 异常的变量名1){
// 异常发生时,系统将异常封装成Exception对象变量名1,传递给catch
// 这里的代码可以对变量名1进行处理
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 无论有无异常,均执行这里的代码,通常为释放资源
}
//Ctrl + Alt + T 自动生成
- 如果异常发生了,则异常语句后面的代码不会执行,直接进入到catch块
- 如果异常没有发生,则顺序执行try代码块,不会进入到catch
- 如果希望不管是否发生异常,都执行某段代码(如关闭连接,释放资源)则放入finally。
- 可以有多个catch语句,捕获不同的异常,但要子类异常在前,父类异常在后。
- 可以进行try-finally配合使用,相当于没有捕获异常,因此程序会直接退出(return 0;)。无论是否发生异常,都必须执行finally语句。
抛出异常(throws)
如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。
public void deposit(double amount) throws RemoteException
{
throw new RemoteException();
}//一般用在方法中
- 对于编译异常,程序中必须处理,比如 try-catch 或者 throws
- 对于运行时异常,程序中如果没有处理,默认就是 throws 的方式处理
- 使用throws,抛出异常,让该方法的调用者处理,层层向上传递。
- 在方法声明中用 throws语句可以声明抛出异常的列表, throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类,也可以是异常列表。
- 子类重写父类的方法时,对抛出异常的规定:孑类重与的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型。
自定义异常
在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。
- 所有异常都必须是 Throwable 的子类。
- 如果希望写一个检查性异常类,则需要继承 Exception 类。
- 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。
可以像下面这样定义自己的异常类:
class MyException extends Exception{
}
只继承Exception 类来创建的异常类是检查性异常类。
下面的 InsufficientFundsException 类是用户定义的异常类,它继承自 Exception。
一个异常类和其它任何类一样,包含有变量和方法。