一、异常的产生
1. 在java代码中,如果发生异常,JVM就会中断程序代码的运行,然后创建异常对象并抛出。例如:
int a=2, b=0;
int i=a/b; //除数不能为0,发生异常
System.out.println(i);
程序会在执行第2行代码时中断,并抛出异常,导致后面的代码无法执行。
2. 但是,有些情况程序员认为是异常的,而在JVM看来却是正常的,比如说:
int age;
age = -100;
System.out.println(age);
int age;
age = -100;
System.out.println(age);
对于JVM来说,这只是正常的赋值语句,但在我们眼中这就不正常了,谁的年龄会是负的呢。
所以,在这种情况下我们就需要自己手动创建并抛出异常,这就需要用到throw了:
int age;
age = -100;
age = -100;
if (age<0)
{
Exception e = new Exception("Age Exception"); //创建异常对象
throw e; //抛出异常
throw e; //抛出异常
}
System.out.println(age);
System.out.println(age);
注:JVM创建的异常对象会由JVM自动抛出,而程序员创建并抛出的对象必须通过throws或try{}catch(){}进行相应处理。
二、异常的处理
当异常发生后就要作相应处理,常用的处理手法有throws和try{}catch(){}:
1. 定义一个方法时如果使用throws,如:
public void someMethod() throws Exception
{
//do something
}
就表示该方法可能抛出某种异常,那么该方法的调用者就必须处理该方法抛出的异常,可以继续使用throws抛出或者使用try{}catch(){}捕捉,如果异常被抛到顶层都没有捕捉就会将异常信息显示于顶层(控制台或页面);
2. 如果在一段代码中使用try{}catch(){},如:
public void someMethod()
{
try
{
int a=2, b=0;
int i=a/b; //除数不能为0,发生异常,try{}块中止运行
System.out.println(i); //无法执行
}
catch(Exception e)
{
System.out.println("发生异常!"); //捕捉到异常并处理
}
System.out.println("我仍然继续!"); //正常执行
}
当try{}块中的代码产生异常时,try{}块中的代码就会中断运行,并由catch(){}块捕捉到产生的异常并作相应处理,而
try{}catch(){}后面的代码仍可正常执行。但是,一般不要简单地捕捉顶层的Exception,因为Exception是所有异常的父类,包
括RuntimeException,简单捕捉Exception会将所有类型的Exception全部捕捉,这样不利于异常处理。
当可能发生的异常不止一种时,如:SQLException, IOException,有两种catch方式:
(1)SQLException, IOException无论catch哪种都进行统一处理,如:
try{}
catch(SQLException se, IOException ie) //不推荐
{
//do something
}
(2)分开处理,如:
try{}
catch( IOException ie)
{
//do something
}
catch(SQLException se)
{
//do something
}
在(2)中,如果两种异常属于继承关系,则应按继承关系中从子到父的顺序进行处理,如:
try{}
catch( IOException ie)
{
//do something
}
catch(Exception e)
{
//do something
}
因为IOException继承自Exception,Exception包含IOException,所以,如果将
catch(Exception e){}放到前面就会连IOException一起catch,这样后面的catch(IOException
ioe){}就变得毫无意义。
另外,由于Java有垃圾回收器,所以异常处理并不需要处理内存的回收问题,但是依然有一些资源需要程序员来处理,比如文件、网络连接和图片等
资源,这种情况可以在try{}catch(){}后加上finally{}块进行程序的清理工作,无论try{}块中有没有发生异
常,finally{}块中的代码都一定会被执行。