异常
java语言的一个重要特征就是提供了完善的面向对象异常处理机制,异常处理机制有两个重要的作用:1、定位异常发生的位置;2、绕开异常,不让异常执行,使程序可以正常运行。
一、定位异常发生的位置
首先看这个实例:
public static void main(String[] args){
int a = 5/0;
}
Exception in thread "main" java.lang.ArithmeticException: / by zero
at live.csd.FACTORY.exceptional.main(exceptional.java:7)
在这个实例当中5/0,除数为0,在运行后系统提示出现异常并提示异常出现的原因是除数为0。同时因为这个异常的存在,系统强制终止了程序的运行,在这里我们要了解到,这里的系统提示的异常相关信息是由异常处理机制完成的,Java所有异常类都是 Throwable的子类,它包括Java异常处理的两个重要子类:Error和Exception。在我们使用java编译器编写代码时,当检测到异常时,会运行异常类,追踪栈,给出异常信息,如下列实例:
public static void main(String[] args){
// int a = 5/0;
ArithmeticException arith = new ArithmeticException("/ by zero");
throw arith;
}
Exception in thread "main" java.lang.ArithmeticException: / by zero
at live.csd.FACTORY.exceptional.main(exceptional.java:8)
从上面的实例可以看出我们直接使用ArithmeticException类,抛出得到和先前相同的结果,这说明我们在运行得到的异常提示,和程序中断的结果和5 /0这个计算本身没有直接关系,而是系统在检测到异常时,运行了ArithmeticException类中断程序继续运行,并追踪到异常来源。这就是异常处理机制的一个重要作用,定位异常发生的位置。java代码在文本中运行中时,出现异常,错误都并不会直接告诉你出现的错误类型,位置,原因,是在java编译器中由java工具开发者设置好的异常类检测,对我们的错误进行追踪处理预防。由此我们在自己编写代码时也可以根据自身程序的需要编写异常处理机制,保护程序的正常运行。
二、异常的处理
在编译过程中异常的产生是难以避免的,那么异常的预防和处理就十分重要。
首先我们要了解异常类的结构,
Throwable是所有异常类的父类,有两个直接子类Error和Exception,其中与以Exception为直接父类的异常类是编译异常,以RuntimeException为直接父类的为运行时异常,编译时异常在写代码时要对其可能的出现进行预处理,运行时异常往往有程序内部因素造成,出现概率和影响相对较小,可以不用在编写时进行预处理。
在面对异常时我们要进行处理,但不是删除处理,在程序中异常出现的地方可能被多次调用,进行较大改动可能会造成一连串的问题,在面对异常时常用的两种方法是:1、向上抛出;2、try…catch处理。
首先是用throws抛出下面是实例:
public static void test(String pathName){
File file = new File(pathName);
FileInputStream fis = new FileInputStream(file);
//java: 未报告的异常错误java.io.FileNotFoundException; 必须对其进行捕获或声明以便抛出
}
public static void main(String[] args)throws FileNotFoundException{
test("file");
}
public static void test(String pathName)throws FileNotFoundException {
File file = new File(pathName);
FileInputStream fis = new FileInputStream(file);
}
在上面的代码中可以看到,一开始代码有异常,找不到文件,这时由于java异常处理机制,系统直接显示无法运行要我们做处理,我们选择throws将异常抛出交给调用了异常的方法中去解决,在main方法中依然没有解决,main方法再使用throws就会到JVM中,直接报错终止执行。
我们可以使用try…catch语句来处理异常
public static void main(String[] args){
test("file");
}
public static void test(String pathName){
File file = new File(pathName);
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
System.out.println("异常:文件不存在");
}
System.out.println("程序正常运行");
}
异常:文件不存在
程序正常运行
Process finished with exit code 0
使用try加大括号框住可能出现异常的代码,如果匹配到和catch中形同的异常的类型就由catch作用域中方法处理异常,运行后我们可以看到,程序出现异常,被检测到异常,但程序并没有运行异常,也没有因为异常而被打断。这个时候我们可以理解为,我们让程序”绕过“了异常运行没有异常的部分,因为异常发生在try的作用域中并不能被作用域外的其他方法调用,不会影响到程序整体的运行。