异常处理机制
异常发生的原因
- 用户输入了非法数据
- 要打开的文件不存在
- 网络通信是连接中断,或者 JVM 内存溢出
- 其他一些物理错误
常见的三种异常的类型:
- 检查性异常:最具代表性的检查异常是用户错误或问题引起的异常,这是程序员无法预见的。
- 运行时异常:运行时异常时可能被程序员避免的异常。
- 错误:错误不是异常,而是脱离程序员控制的问题
Exception 类的层次
Exception 和 Error 是 Throwable 的子类
Exception 和 Error 的子类名都是以父类名作为后缀。
注意:如果让一个类成为异常类,必须要继承异常体系,因为只有成为异常体系的子类才有资格具备可抛性
捕获异常
使用 try 和 catch 关键字可以捕获异常。try/catch 代码放在异常可能发生的地方
tyr
{
}catch(Exception e)
{
// Catch 块
}finally{ // 通常用来关闭(释放)资源
}
Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时, try 后面的 catch 块就会被检查。如果发生的异常包含在 catch 块中,异常就会被传递到该 catch 块,这和传递一个参数到方法是一样。
finally 关键字用来创建在 try 代码块后面执行的代码块。
无论是否发生异常,finally 代码块中的代码总会被执行。
在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。
多重捕获块
一个 try 代码块后面跟随多个 catch 代码块的情况就叫多重捕获。
try{
// 程序代码
}catch(异常类型1 异常的变量名1)
{ // 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}
可以在 try 语句后面添加任意数量的 catch 块。
如果保护代码中发生异常,异常被抛给第一个 catch 块。
如果抛出异常的数据类型与 ExceptionType1 匹配,它在这里就会被捕获。
如果不匹配,它会被传递给第二个 catch 块。
如此,直到异常被捕获或者通过所有的 catch 块。
注意下面事项:
- catch 不能独立于 try 存在。
- 在 try/catch 后面添加 finally 块并非强制性要求的。
- try 代码后不能既没 catch 块也没 finally 块。
- try, catch, finally 块之间不能添加任何代码。
throws/ throw 关键字:
如果一个方法没有捕获到一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。
也可以使用 throw 关键字抛出一个异常,无论它是实例化的还是刚捕获到的。
public class className
{
public void fangfa throws RemoteException
{
throw new RemoteException();
}
}
一个方法可以声明抛出多个异常,多个异常之间用逗号隔开。
声明自定义异常
在 Java 中你可以自定义异常。编写自己的异常类时需要记住下面的几点。
- 所有异常都必须是 Throwable 的子类。
- 如果希望写一个检查性异常类,则需要继承 Exception 类。
- 如果你想写一个运行时异常类,那么需要继承 RuntimeException 类。
异常的注意事项:
1.子类在覆盖父类的方法时,父类的方法如果抛出了异常,那么子类的方法只能抛出父类的异常 或者该异常的子类。
2. 如果父类抛出多个异常,那么子类只能抛出父类异常的子集。
简单说: 子类覆盖父类只能抛出父类的异常或者子类或者子集。
注意:如果父类的方法没有抛出异常。那么子类覆盖时绝对不能抛出。