1、异常:在程序运行过程中,如果JVM检测出一个不可能执行的操作时,就会出现运行时错误(runtime error)。在Java中,运行时错误会作为异常抛出。异常就是一种对象,表示阻止正常进行程序执行的错误或情况。如果异常没有被处理,那么程序将会非正常终止。
2、异常类继承层次
异常是对象,异常封装成类Exception,所有的异常都直接或间接继承自Throwable类。Throwable类有两个直接的子类,Error和Exception。可以通过继承Exception或Exception的子类来创建自己的异常类。
- Error是程序无法恢复的严重错误,程序员无能为力,只能让程序终止。如JVM内部发生错误,内存溢出和资源耗尽等。
- Exception是程序可以恢复的异常。如除零异常、空指针访问、网络连接中断、读取不存在的文件等。
3、异常分类
Exception类分为受检查异常和运行时异常
- 受检查异常(必检异常):是除RuntimeException以外的异常,特点是编译器会强制程序员检查并通过try-catch块处理它们,或在方法头进行声明。如处理数据库异常的SQLException,处理读写异常的IOException。
- 运行时异常(免检异常):是继承RuntimeExceptionl类的直接或间接类。编译器不检查这类异常是否进行了处理,也就是对于这类异常不捕获也不抛出,程序也可以编译通过。一旦运行时异常时就会导致程序的终止。如访问一个数组的越界元素,会抛出一个IndexOutofBoundsException异常。
运行时异常应用举例:
public static void main(String[] args) {
System.out.println("start");
int a[]= {1,2,3,4};
System.out.println(a[4]);//越界访问数值
System.out.println("following action");
}
4、异常的处理模型
Java的异常处理模型基于三种操作:声明一个异常、抛出一个异常、捕获一个异常。
(1)try-catch语句
try{
//可能会发生异常的语句
}
catch(Throwable e) //e是捕获异常的对象,必须是Throwable的子类
{
//处理异常e
}
try代码块中应该包含执行过程中可能会发生异常的语句。
catch代码块:每个try代码块可以伴随着一个多个catch代码块,用于处理try代码中可能发生的多种异常。
(2)多catch代码块
try{
//可能会发生异常的语句
}
catch(Throwable e) //e是捕获异常的对象,必须是Throwable的子类
{
//处理异常e
}
catch(Throwable e)
{
//处理异常e
}
catch(Throwable e)
{
//处理异常e
}
在多个catch代码情况下,当一个catch代码块捕捉到一个异常时,其他的catch代码块就不再进行匹配。当捕获多个异常之间存在父子关系时,捕获异常顺序与catch代码的顺序相关。一般先捕获子类,后捕获父类。
(3)try-catch-finally语句
try{
//可能会发生异常的语句
}
catch(Throwable e) //e是捕获异常的对象,必须是Throwable的子类
{
//处理异常e
}
catch(Throwable e)
{
//处理异常e
}
catch(Throwable e)
{
//处理异常e
}
finally{
//释放资源,释放非java资源,非java资源不能被垃圾回收器回收
}
无论try正常结束还是catch异常结束,都会执行finally代码块。
finally用处;
(4)throws与声明方法抛出异常
通过throws自定义异常
public static void checkData(int data)throws Exception
{
if(data<0)
throw new Exception("Data Error");
else
{
System.out.println("数据大于等于0 ");
}
}
public static void main(String[] args) {
try
{
checkData(-10);
}
catch(Exception e)
{
e.printStackTrace();
}
finally {}
}
throw和throws的使用要点:
- throws出现在声明方法的位置,而throw出现在函数体中。
- 如果在某个函数内部用throw抛出了异常,那么在声明该函数时,一定要配套使用throws,否则会出现语法错误。
- 如果在某个函数的声明位置出现了用throws抛出异常的情况,那么需要用try...catch代码块来包含调用的代码,否则也会出现语法错误。
5、异常处理部分的使用要点
(1)尽量用try...catch...finally的语句来处理异常,在finally中应当尽可能地回收内存资源。
(2)尽量减少用try监控的代码块。避免在一个try中监控过多的代码。
(3)先用专业的异常来处理,最后用Exception异常来处理。
(4)catch从句中,不要只简单地抛出异常,要尽可能地处理异常。
(5)出现异常后,尽可能保证项目不会终止,把异常造成的影响降低最低。