Java异常
简介: JAVA异常处理的目的是为保证程序在出错之后,依旧可以执行一些其它操做。该操作可以是用户的其它行为,也可以是保存程序运行后的一些结果,还可以是合理的结束程序的运行。
为了达到上述目的。异常处理应该具备以下几点
- 捕获异常
- 向用户通知出现的异常类型
- 保存出现异常前的程序运行结果
- 提供发生异常后的退出机制和处理机制
在JAVA中提供了一种处理异常的机制,该机制通过捕获异常,并把程序的控制权,从异常的发生地点转移到处理异常的程序代码处。这样,用户就编写对应的代码,来处理可能出现的异常,然后执行一些其它操作比如提示异常的原因,保存程序运行的结果或者正取的关闭程序。
异常分类
处理异常之前,需要知道发生异常的原因。如果不知道异常发生的原因而对异常进行处理,往往会出现更多的异常。比如异常发生的原因是数组越界,但处理的方式是关闭正常运行I/O流。这样就会导致程序的运行结果不正确,比如正在保存的文件丢失。
但发生异常的原因多如牛毛,列举出所有可能出现的异常原因显然是不太可能的,所以JAVA也只是抽象出了一些比较典型的异常情况来进行异常的分类,并通过面向对象的思想进行组织。
在JAVA中,所有的异常都继承自 Throwable
类,并在其下分出两个分支。分别是Error
和 Exception
。
Error
处理的唯一方式是尽最大努力保障程序的安全退出,是用户无法处理的异常。因为 Error
的发生往往意味着,JAVA系统内部出错或者是计算机系统的资源耗尽。比如内存耗尽,栈溢出等错误。
Exception
代表的分支是用户可以进行处理的异常,该Exception
下面又分为两大类异常,分别是I/O异常(IOException)和运行时异常(RuntimeException)。
I/O异常往往出现的原因不一定是程序员编写的代码出现了问题,也可能是操作系统把某个I/O资源给移除了,导出出现了I/O异常。
但运行时异常(RuntimeException) 一定是代码编写中出现了问题,比如数组越界,除0操作,出现空指针、不正确的类型转换等异常情况。
我们可以通过这张图来了解JAVA中的异常层次结构。
代码中的异常处理
异常往往出现在执行的方法中,如果一个方法在调用的过程中,可能出现某种异常。那么应该在该方法的头部进行声明,表明该方法可能出现的异常的类型。以通知编译器,在调用该方法的时候,必须应对可能出现的问题。而使用该方法的用户就必须为该方法可能出现的异常进行捕获处理。声明异常的方式如下,如果我们定义了一个方法,该方法在运行的时候,不能接受0作为参数,那么我们就可以参数为0的时候,抛出异常。
public class Main {
public static void main(String[] args) {
}
}
class TestException{
void show (int i) throws Exception {
System.out.println("我是可能出现异常的代码段,如果i等于0,我就会异常");
if (i == 0){
throw new Exception("i=0,是错误的");
}
}
}
由于在方法头部声明了会出现异常,所以我在调用方法的时候,就必须使用try{}catch{}
来捕获和处理异常,如下代码。
没使用try{}catch{}
,编译器报错。
使用try{}catch{}
编译器没有报错
但我们传入的参数是0的时候,该代码就会出现异常,程序的控制权,就会从出现异常的地方转移到处理异常的地方。修改程序如下
public class Main {
public static void main(String[] args) {
TestException exception = new TestException();
try {
/**try代码块监视异常**/
exception.show(1);
System.out.println("方法成功执行完了。没有异常");
}catch (Exception e){
/**catch捕获出现的异常,并进行处理,该处理是打印异常消息**/
System.out.println("我是处理异常的地方");
e.printStackTrace();
}
}
}
class TestException{
void show (int i) throws Exception {
System.out.println("我是可能出现异常的代码段,如果i等于0,我就会异常");
if (i == 0){
throw new Exception("i=0,是错误的");
}
System.out.println("我在排除异常的后面");
}
}
执行程序结果:
传入正常参数程序的处理结果
通过比较,可以得出。当方法抛出异常之后,那么该方法后面的所有代码将不会执行,并且在try语句块后面的代码也不会执行,
而是跳转到处理异常的 catch{}
中执行。