如果程序发生异常,系统首先创建异常对象交给运行时系统,再由系统寻找代码处理异常,共经历抛出异常、捕获异常和处理异常几个过程。下列程序段会发生异常:
class Rdd
{
public static void main(String []args)
{
int i=9;
int j=9;
int s=39/(i-j);
}
}
java异常处理通过五个关键字来实现:try,catch,throw,throws,finally.
1:try-catch-finally语句
具体的异常处理结构用try-catch-finally块来实现。try块存放可能出现异常的java语句;catch用来捕获发生的异常,并对异常进行处理;finally块用来清除程序中为释放的资源。不管try块代码如何返回,finally块都总是被执行。具体格式如下:
try{
可能出现异常的语句;
}
catch(异常类 异常类对象名)
{
处理代码;
}
finally
{
必须执行的语句;
}
其中把可能会发生异常情况的代码放在try语句段中,利用try语句对这组代码进行监视。如果发生异常,程序就转去catch部分来查询异常
,catch给出所有可能出现异常的类型,可以有多个。如果发生了第一种异常,使用第一个catch中的代码段处理;如果出现了第二种异常,则使用第二个catch代码中的代码段处理,以此类推。catch可能执行,也可能不执行。如果try里面没有产生异常,catch就不执行。如果有异常,catch语句在执行前,必须识别抛出的异常 是catch能够捕获的异常。如果catch语句参数中声明的异常类与抛出的异常类相同,或者是它的父类,catch语句就可以捕获任何这种类的对象。如果发生的异常没有捕获到,那么流程控制将沿着调用堆栈一直向上传。如果直到最后还是没有发现处理异常的catch语句,那么在finally子语句执行完之后,调用ThreadGroup的unCaughtExpection()方法终止当前的线程(即发生了异常的线程)。
finally可以有,也可以没有,但无论异常是否发生,finally子语句都是必须执行的语句。这样即使发生的异常与catch所能捕获的异常不匹配也会执行finally子语句。
异常处理示例:
class Test12
{
publiic static void main(String []args)
{
med(1);
med(0);
med(50);
}
static void med(int i)
{
try{
System.out.println("i"=+1);
int b=50/i;
int a[]={0,1,2};
a[i]=b;
}
catch(ArithmeticExpection e1){
System.out.println("Expection is:"+e1);
}
catch(IndexOutOfBoundsExpction e2){
System.out.println("Expection is:"+e2);
}
finally{
System.out.println("Program is end!");
}
}
在该段程序中,首先调用med(1),传递给形参i=1,在try中不会发生异常,catch语句不执行,程序执行完后try直接跳到finally执行。其次调用med(0),传递形参给i=0,在try中执行“int b=50/i;”时抛出异常,这时程序就会查出第一个catch,看是否是该catch抛出的异常。是执行该catch后面的语句,输出异常"java.lang.ArithmeticExpection"然后程序转去执行finally语句。最后调用med(50),传递参数给i=50,在执行try的过程中“a[i]=b;”处发生数组下标越界异常,程序转去执行catch,第一个catch不是我们抛出的异常。一次判断第二个异常,是第二个catch所指出的异常,程序就会执行该catch后面的代码,该输出异常为“java.lang.ArrayIndexOutOfBoundsExpection”最后执行finally里面的语句。