Java中的异常处理
在没有异常处理的程序中如果要回避异常,需要使用大量的判断语句,配合所想到的错误状况来捕捉程序中可能发生的错误。但是这样势必会导致程序运行效率降低。
Java异常处理机制具有易于使用,可自定义异常类,处理抛出的异常的同时,又不会降低程序运行效率等优点。因而在Java程序设计时,应充分的利用异常处理机会,以增进程序的稳定性及效率。
异常分为:
1、编译器异常(变红)Thread.sleep(1000); 文件IO; FileInputSteam
编译期异常
2、运行期异常 (前面所见的各种异常):数组下标越界、除零操作/0、空指针异常(如果发生空指针异常,对所在点访问操作进行判断)
3、使用Try…catch语句捕捉异常
(如果会发生异常的语句发生异常,此时该语句(在Try块)之后的所有语句都不会被执行到)
finally块 Try{ }catch(Exception){} finally()
无论try是否发生异常,都会走到Finally块
throws 抛出异常类型(自己不处理,谁用谁处理)
throw:抛出异常对象
if(arr==null){
throw new Exception;
}
Object:所有类默认继承Object
Exception和error:
共同点:
Exception和error是java异常结构中最常用的两个类,统称为异常。它们都是throwable的子类
不同点:
Exception表示程序中遇到的异常,可以用try catch进行捕获
error一般指jvm错误,程序中无法捕获
(拓展:Throwable是Exception的父类,可不可以直接使用Throwable呢?
首先,使用Throwable捕获异常,在代码中是没有任何问题的,但在开发中一般不会使用Throwable处理,因为其有Exception和error两个子类,Error本身不需要程序处理,而程序中需要处理的是Exception 所以没有必要使用Throeable)
异常处理的基本方法:
在编写代码处理异常时,对于检查异常,有2种不同的处理方式:使用try…catch…finally语句块处理它。或者,在函数签名中使用throws 声明交给函数调用者caller去解决。
finally块
finally块不管异常是否发生,只要对应的try执行了,则它一定也执行。只有一种方法让finally块不执行:System.exit()。因此finally块通常用来做资源释放操作:关闭文件,关闭数据库连接等等。
良好的编程习惯是:在try块中打开资源,在finally块中清理释放这些资源。
需要注意的地方:
1、finally块没有处理异常的能力。处理异常的只能是catch块。
2、在同一try…catch…finally块中 ,如果try中抛出异常,且有匹配的catch块,则先执行catch块,再执行finally块。如果没有catch块匹配,则先执行finally,然后去外面的调用者中寻找合适的catch块。
3、在同一try…catch…finally块中 ,try发生异常,且匹配的catch块中处理异常时也抛出异常,那么后面的finally也会执行:首先执行finally块,然后去外围调用者中寻找合适的catch块。
Throw和Throws关键字
Throws:在定义一个方法时,使用Throws关键字声明,表示此方法不处理异常,而是交给调用方法来处理
(注意:不要在main方法中使用throws,main方法为一切方法的起点,一切的操作也是由主方法开始的,所以,如果在主方法中使用throws,则程序出现问题后肯定交由jvm处理,将会导致程序中断。)
Throw:Throw关键字是人为的抛出异常,直接抛出异常的实例化对象。
try{
throw new Exception("自己抛出异常"); //抛出异常的实例化对象
}catch(Exception e){
e.printStackTrace(); //捕获异常
}
自定义异常类:
如果要自定义异常类,则扩展Exception类即可,因此这样的自定义异常都属于检查异常(checked exception)。如果要自定义非检查异常,则扩展自RuntimeException。
按照国际惯例,自定义的异常应该总是包含如下的构造函数:
一个无参构造函数
一个带有String参数的构造函数,并传递给父类的构造函数。
一个带有String参数和Throwable参数,并都传递给父类构造函数
一个带有Throwable 参数的构造函数,并传递给父类的构造函数。
代码如下:
public class MyException extends Exception{ //自定义异常类继承Exception类
public MyException(String msg){ //构造方法接受异常信息
super(msg); //调用父类中的构造方法
}
}
public class test {
public static void main(String[] args) {
try{
throw new MyException("自定义异常信息");//抛出异常
}catch(Exception e){ //异常捕获处理
e.printStackTrace();
}
}
}