Java异常
在java中异常机制主要依赖于try,catch,finally,throw,throws五个关键字,其中try关键字后面要紧跟一个花括号扩起来的代码块,在try块中我们可以放置许多可能引发异常的代码。catch后面跟着一个异常类型和一个代码块,表示该catch快用于处理这个类型的代码块。多个catch后还可以接finally,finally用于回收在try块中打开的物理资源,异常机制会保证finally执行。如果一个方法没有捕获一个检查性异常,那么该方法必须使用 throws 关键字来声明。throws 关键字放在方法签名的尾部。也可以使用 throw 关键字抛出一个异常。
我们还要注意,在捕获异常中要先处理小异常,再捕获大异常。
异常的体系结构图,在这张图中我们可以知道,这些异常类之间有严格的继承关系,我们也可以发现exception和error他们两个都继承了Throwable类。而error表示的是不想被程序捕获或者是无法处理的错误,而exception表示的是程序可以处理的异常。
捕获异常
使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。也就是系统把所有业务实现的代码放入到try块中,而把所有异常处理的逻辑放入到catch中进行处理。
啊try主要用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
catch主要用于捕获异常,主要在try块中捕获。
try/catch 的语法如下:
try
{
// 程序代码
}catch(ExceptionName e1)
{
//catch 块
}
就相当于,我们试图去编译程序的时候,如果遇到了错误,我们就捕获到这个错误,然后再在catch中进行相应的处理。还需要注意的是在try块中声明的变量是代码块中的局部变量,在catch块中是不能访问的,只能在try块中生效。
多重捕获块
多重捕获块的意思就是一个try后面跟着许多个catch块,然后在捕获异常中一个一个的去比较,去判断。在多重捕获中我们要按照先小后大,也就是说先子类后父类的规则顺序。
例如:
public class DivTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
try
{
int a = Integer.parseInt(args[0]);
int b = Integer.parseInt(args[0]);
int c = a/b;
System.out.println(c);
}
catch (IndexOutOfBoundsException ie) //参数的个数不够
{
ie.printStackTrace();
}
catch (NumberFormatException ne)//数字格式异常
{
ne.printStackTrace();
}
catch (ArithmeticException ae)//算术异常
{
ae.printStackTrace();
}
catch (Exception e)//未知异常
{
e.printStackTrace();
}
}
}
上面的代码段包含了4个catch块。可以在try语句后面添加任意数量的catch块。如果保护代码中发生异常,异常被抛给第一个 catch块。如果抛出异常的数据类型与第一个匹配,它在这里就会被捕获。如果不匹配,它会被传递给第二个catch块。如此,反复操作直到异常被捕获或者通过所有的 catch 块。
finally关键字
finally 关键字用来创建在 try 代码块后面执行的代码块。无论是否发生异常,finally 代码块中的代码总会被执行。在 finally 代码块中,可以运行清理类型等收尾善后性质的语句。finally 代码块出现在 catch 代码块最后,语法如下:
try{
// 程序代码
}catch(Exception e){
// 程序代码
}
finally{
// 程序代码
}
除非try块和catch块调用了退出虚拟机的方法,否则不管在try块和catch块中执行了怎么样的代码,出现什么样的情况,异常处理分finally都会被执行。
在finally块中要少使用throw和return等语句,这样有可能会导致一些错误的发生。还有就是在finally块中使用了return和throw等终止方法时,就会直接停止。
throw和throws关键字
throws声明的抛出异常,就是在当前的方法中不知道如何处理这个类型异常的时候,该异常应该由上一级调用者处理,如果main方法也不知道如何处理这个异常,也可以使用throws声明来抛出异常,将这个异常交给JVM处理。throws 关键字放在方法的尾部。
throw语句可以单独的使用,throw的作用就是抛出异常,throw语句抛出的不是异常类,而是一个异常实例,而且每次只能抛出一个异常,在throw语句执行后就会立即停止,throw后面的语句都不会被执行,格式如下:
throw ExceptionInstance;
public class className
{
public void deposit() throws Exception
{
throw new Exception();
}
}
对于throw关键字的使用,我还不怎么清楚,使用这里就不解释了。
一个方法可以抛出多个异常,在抛出时用逗号隔开,例如:
public class className
{
public void withdraw(double amount) throws Exception,IOException
{
}
}
我们在异常的运行过程中要注意以下几点
1.finally语句不被执行的唯一情况就是先执行了用于终止程序的System.exit()方法。
2.return语句用于退出本方法时,finally语句仍会执行。
3.finally代码块虽然在return语句之前就被执行,但它的变量修改不会影响返回值。