Logo

郎哥编程

处理异常的方法和过程

2021-07-02 230

学习目标:掌握程序异常产生的原因,处理异常的方法和过程。

如何处理程序异常?

编写Java程序经常会遇到错误。一类错误是语法错误或资源链接错误,此类错误一般在编译过程中就可以发现;另一类错误是在程序运行过程中出现的错误,该类错误被称为程序异常,由于程序异常严重影响了程序运行的稳定性。因此,程序人员必须要对此类错误进行预防和处理,对异常处理的过程即异常处理。

在工作和现实生活中,也有很多异常处理的事例。例如,在软件项目开发过程中,团队成员的突然离职、客户对需求的变更、开发进度拖延等情况的发生,都会导致项目开发过程出现异常,并需要项目经理及时处理这些异常情况。

异常不可避免,但可以对异常做出预测和预处理,预测什么情况下会出现异常,出现异常后如何处理。

例如,前面谈到的软件项目开发过程出现的异常,可以在项目管理计划书中针对团队成员离职、需求变更、进度拖延出现的异常,制定详尽的应对计划,该应对计划就是异常处理。

对于程序而言,内存溢出、数组越界、除零操作、对象没有实例化就使用、变量无赋值就使用等操作都会引发程序异常。因此,程序员在编写代码时,需要对上面的情况做出预测,并添加出现异常时的处理语句,以提高程序的稳定性。

在不支持异常处理的程序设计语言中,程序员为了检查可能发生的异常情况,需要使用很多的if—else语句,这就要求程序员非常清楚地知道是什么导致了异常的产生,以及异常的确切含义。

案例1:建立一个测试类,使用if-else语句处理程序可能出现的错误。

新建项目PUnit9,在PUnit9项目新建excep包,在excep包下新建ExecpTest类。代码如下:

package excep;
 
public class ExecpTest {
    public static void main(String[] args) {
        int ret = div(20,0);
        System.out.println("除法结果为:" + ret);
 
    }
 
    //求两数的除法
    public static int div(Integer a,Integer b)
    {
        int ret = -1;
        //预测传入参数a为空的异常处理代码
        if( a == null )
        {
            System.out.println("传入的参数a为空");
            return ret;
        }
        //预测传入参数b为空的异常处理代码
        else if( b == null )
        {
            System.out.println("传入的参数b为空");
            return ret;
 
        }
        //预测传入参数b不能为0的异常处理代码
        else if( b == 0 )
        {
            System.out.println("传入的参数b为0,b做为除数不能为0");
            return ret;
 
        }
        ret = a / b;
        return ret;
 
    }
 
}

程序执行结果如下图所示:

06.png

有异常处理机制的语言,没有必要去编写上述的这些if—else语句。在默认的情况下,异常会输出一个错误消息,并中止程序的执行。为了更好地处理异常情况,程序员通常会在程序中定义异常处理语句来捕获和处理异常情况。Java语言提供了try—catch语句来捕获和处理异常,try—catch语句后面会详细讲解。

案例2:使用try—catch语句对上面的案例提供异常处理的支持。

在excep包下新建TryCatchTest类。代码如下:

package excep;
 
public class TryCatchTest {
    public static void main(String[] args) {
        int ret = div(20,0);
        System.out.println("除法结果为:" + ret);
 
    }
 
    // 求两数的除法
    public static int div(Integer a,Integer b)
    {
        int ret = -1;
        //try语句块用于捕获异常
        try {
            ret = a / b;
        }catch(Exception e1){
            //catch语句块用于处理异常
            System.out.println(e1.getMessage());
        }
        return ret;
    }
 
}

采用try—catch语句不仅可以使代码变得更简洁,而且能为程序调试提供很大的方便,从而达到提高程序稳定性的目的。

异常处理就是提前预测程序可能发生的所有异常情况,并通过Java提供的异常处理类捕获异常,编写异常处理代码。当出现异常后,程序执行的流程发生改变,程序的控制权转移到异常处理代码。

程序异常及异常处理类

前面介绍了Java的异常处理,对异常有了大概了解。现在再从编码的角度来理解异常。试运行如下代码:

案例3:建立ShowException类,在main()方法中进行除零操作,查看控制台给出的异常信息。

在excep包下新建ShowException类。代码如下:

package excep;
public class ShowException {
    public static void main(String[] args) {
        Integer a=30,b=0,c;
        //零做为除数,程序抛出异常
        c= a / b;
    }
}

上面的代码中,b为零值,当执行c= a / b语句时,程序抛出异常,控制台会显示如下图所示的内容:

07.png

当然如果程序员对变量b做了预防为0的判断,控制台将不会显示图中所示内容。控制台给出的错误信息就是异常,也就是程序运行过程中出现的错误或不正常的情况,当发生异常时,程序可能会出现问题,甚至崩溃。因此当程序发生异常时就需要对异常进行处理,Java语言也提供了异常处理机制。

Java提供了一个Throwable类,Throwable类是Java语言中所有处理错误或异常的超类,只有当对象是此类或其子类之一的实例时,才能通过Java虚拟机或者java的throw语句抛出异常。类似的,只有此类或其子类之一才可以是catch子句中的参数类型。它的两个子类的实例Error和Exception通常用于指示发生了异常情况。这些实例是在异常情况的上下文中创建的,因此包含了相关的程序运行信息。Throwable类及其子类的结构如下图所示:

11.jpg

Throwable类充当所有对象的父类,可以使用异常处理机制将这些对象的异常抛出并捕获。在Throwable类中定义方法来检索与异常相关的错误信息,并打印显示异常发生的栈跟踪信息。它有Error和Exception两个基本子类。

错误(Error):

JVM系统内部错误,资源耗尽等严重情况。

异常(Exception):

其它因编程错误或偶然的外在因素导致的一般性问题。例如,除数为零、数组越界、空指针访问、读取不存在的文件等。

当发生Error时,程序员根本无能为力,只能让程序终止。例如内存溢出,不可能指望程序能处理这样的情况。而对于Exception,则有补救或控制的可能,程序员也可以预先防范。异常处理主要是针对Exception进行,Exception的API说明如下图所示:

08.png

图中包含了众多Exception类的已知子类,也不必担心这么多子类记不住,在实际使用时查阅异常类的文档即可。

下面列出常见的异常类:

Exception:

异常层次结构的根类

RuntimeException:

Java.lang异常的基类

ArithmeticException:

算术错误异常类,如零作为除数

ArrayIndexOutOfBoundsException:

数组越界异常处理类

NullPointerException:

尝试访问NULL 对象或成员

ClassNotFoundException:

不能加载所需的类

IOException:

I/O异常的根类

异常处理机制可以从两个方面来描述,当一个Java程序违法了Java语义规范时,JVM虚拟机就会抛出一个异常。例如数组下标越界,会引发IndexOutOfBoundsException异常,访问null的对象时会引发NullPointerException异常。另一种情况就是JAVA允许程序员扩展这种语义检查,程序员可以创建自己的异常,并自由选择在何时用throw关键字引发异常。所有的异常都是java.lang.Thowable的子类。

代码在线纠错(通义千问 qwen-max)

支持粘贴多个代码文件,提交后由阿里云通义千问自动分析代码漏洞、语法错误、逻辑问题并给出修改建议。
您已解锁 AI 代码纠错功能,可正常使用!

评论区

登录 后发表评论
暂无评论