首页 > 编程语言 >Java异常处理规则

Java异常处理规则

时间:2022-11-19 21:24:18浏览次数:36  
标签:Java 处理 代码 程序 try 规则 catch 异常

Java异常处理规则

前面介绍了使用异常处理的优势、便捷之处,本节将进一步从程序性能优化、结构优化的角度给出异常处理的一般规则。成功的异常处理应该实现如下4个目标:

  • 使程序代码混乱最小化。
  • 捕获并保留诊断信息。
  • 通知合适的人员。
  • 采用合适的方式结束异常活动。

下面介绍达到这种效果的基本准则。

1.* 不要过度使用异常

不可否认,Java的异常机制确实方便,但滥用异常机制也会带来一些负面影响。过度使用异常主要有两个方面:

  • 把异常和普通错误混淆在一起,不再编写任何错误处理代码,而是以简单地抛出异常来代替所有的错误处理。
  • 使用异常处理来代替流程控制。

熟悉了异常使用方法后,程序员可能不再愿意编写烦琐的错误处理代码,而是简单地抛出异常。实际上这样做是不对的,对于完全已知的错误,应该编写处理这种错误的代码,增加程序的健壮性;对于普通的错误,应该编写处理这种错误的代码,增加程序的健壮性。只有对外部的、不能确定和预知的运行时错误才使用异常。

对比前面中,处理用户输入坐标点已有棋子的两种方式:

点击查看代码
//如果用户试图下棋的坐标点已有棋子了
if (!gb.board[xPos -1][yPos -1].equals("+")) {
    System.out.println("您输入的坐标点已有棋子了,请重新输入");
    continue;
}

上面这种处理方式检测到用户试图下棋的坐标点已经有棋子了,立即打印一条提示语句,并重新开始下一次循环。这种处理方式简洁明了,逻辑清晰。程序的运行效率也很好,程序进入if块后,即结束了本次循环。

如果将上面的处理机制改为如下方式:

点击查看代码
// 如果用户试图下棋的坐标点已经有棋子了,程序自行抛出异常
if (!gb.board[xPos -1][yPos -1].equals("+")) {
    throw new Exception("您试图下棋的坐标点已经有棋子了");
}

上面的处理方式没有提供有效的错误处理代码,当程序检测到用户试图下棋的坐标点已经有棋子时,并没有提供相应的处理,而是简单地抛出了一个异常。这种处理方式虽然简单,但Java运行时接收到这个异常后,还需要进入相应的catch块来捕获该异常,所以运行效率要差一些。而且用户下棋重复这个错误完全是预料的,所以程序完全可以针对该错误提供相应的处理,而不是抛出异常。

必须指出:异常处理机制的初衷是将不可预期异常的处理代码和正常的业务逻辑处理代码分离,因此绝不要使用异常处理来代替正常的业务逻辑判断。

另外,异常机制的效率比正常的流程控制效率差,所以不要使用异常处理来代替正常的程序流程控制。例如,对于如下代码:

点击查看代码
//定义一个字符串数组
String[] arr = {"Hello" , "Java" , "Spring"};
//使用异常处理来遍历arr数组的每个元素
try {
    int i = 0;
    while(true){
        System.out.println(arr[i++]);
    }
} catch (ArrayIndexOutOfBoundsException ae) {

}

运行上面程序确实可以实现遍历arr数组元素的功能,但这种写法可读性较差,而且运行效率也不高。程序完全有能力避免产生ArrayIndexOutOfBoundsException异常,程序“故意”制造这种异常,然后使用catch块去捕获该异常,这是不应该的。将程序改为如下形式肯定要好得多:

点击查看代码
String[] arr = {"Hello" , "Java" , "Spring"};
for (int i = 0; i < arr.length; i++) {
    System.out.println(arr[i]);
}

注意:异常只应该用于处理非正常的情况,不要使用异常处理来代替正常的流程控制。对于一些完全可预知,而且处理方式清楚的错误,程序应该提供相应的错误处理代码,而不是将其笼统地称为异常。

1.* 不要使用过于庞大的try块

很多初学异常机制的读者喜欢在try块里放置大量的代码,在一个try块里放置大量的代码看上去“很简单”,但这种“简单”只是一种假象,只是在编写程序时看上去比较简单。但因为try块里的代码过于庞大,业务过于复杂,就会造成try块中出现异常的可能性大大增加,从而导致分析异常原因的难度也大大增加。

而且当try块过于庞大时,就难免在try块后紧跟大量的catch块才可以针对不同的异常提供不同的处理逻辑。同一个try块后紧跟大量的catch块则需要分析它们之间的逻辑关系,反而增加了编程复杂度。

正确的做法是,把大块的try块分割成多个可能出现异常的程序段落,并把它们放在单独的try块中,从而分别捕获并处理异常。

1.* 避免使用catch all语句

所谓catch all语句指的是一种异常捕获模块,它可以处理程序发生的所有可能异常。例如,如下代码片段:

点击查看代码
try {
    //可能引发Checked异常的代码
} catch (Throwable t) {
    //进行异常处理
    t.printStackTrace();
}

不可否认,每个程序员都曾经用过这种异常处理方式;但在编写关键程序时就应避免使用这种异常处理方式。这种处理方式有如下两点不足之处:

  • 所有的异常都采用相同的处理方式,这将导致无法对不同的异常分情况处理,如果要分情况处理,则需要在catch块中使用分支语句进行控制,这是得不偿失的做法。
  • 这种捕获方式可能将程序中的错误、Runtime异常等可能导致程序终止的情况全部捕获到,从而“压制”了异常。如果出现了一些“关键”异常,那么此异常也会被“静悄悄”地忽略。

实际上,catch all语句不过是一种通过避免错误处理而加快编程进度的机制,应尽量避免在实际应用中使用这种语句。

1.* 不要忽略捕获到的异常

不要忽略异常!既然已捕获到异常,那catch块理应做些有用的事情,处理并修复这个错误。catch块整个为空,或者仅仅打印出错信息都是不妥的!

catch块为空就是假装不知道甚至瞒天过海,这是最可怕的事情,程序出了错误,所有的人都看不到任何异常,但整个应用可能已经彻底坏了。仅在catch块里打印错误跟踪栈信息稍微好一点,但仅仅比空白多了几行异常信息。通常建议对异常采取适当措施,比如:

  • 处理异常。对异常进行合适的修复,然后绕过异常发生的地方继续执行;或者用别的数据进行计算,以代替期望的方法返回值;或者提示用户重新操作......总之,对于checked异常,程序应该尽量修复。
  • 重新抛出新异常。把当前运行环境下能做的事情尽量做完,然后进行异常转译,把异常包装成当前层的异常,重新抛出给上层调用者。
  • 在合适的层处理异常。如果当前层不清楚如何处理异常,就不要在当前层使用catch语句来捕获该异常,直接使用throws声明抛出该异常,让上层调用者来负责处理该异常。

标签:Java,处理,代码,程序,try,规则,catch,异常
From: https://www.cnblogs.com/hzhiping/p/16907235.html

相关文章

  • Java使用throw抛出异常
    Java使用throw抛出异常当程序出现错误时,系统会自动抛出异常;除此之外,Java也允许程序自行抛出异常,自行抛出异常使用throw语句来完成(注意此处的throw没有后面的s,与前面声明抛......
  • 多数据源配置时validationQuery的问题(errorCode 923, state 42000 java.sql.SQLSynta
    起初,数据库配置为:datasource:master:url:jdbc:postgresql://ip:5432/databaseNameusername:**password:**......
  • java html串转换成文本串
    采用htmlparser来解决将html串中抽取出文本串。Stringstr="<!DOCTYPEHTMLPUBLIC\"-//W3C//DTDHTML4.0Transitional//EN\">"+"<HTML><HE......
  • java 序列化 浅克隆 深克隆
    序列化Java序列化技术可以使你将一个对象的状态写入一个Byte流里,并且可以从其它地方把该Byte流里的数据读出来,重新构造一个相同的对象。当两......
  • java与Access 数据库连接访问表 例子
    Java与数据库的连接对于一些中大型的主流数据库而言,一般数据库厂商都提供了专门的JDBC驱动.但对于部分小型数据库而言经常没有专门的JDBC数据库连接......
  • Java的内部类
    java内部类内部类的定义在一个类的内部再定义一个完整的类特点编译后可以生成独立的字节码文件内部类可以访问外部类的私有成员,而不破坏封装性可为外部类提供必要的......
  • java poi 读取.doc审阅 修订 最终状态 问题
    一、前景    在使用javapoi读取.doc文件,遇到审阅修订功能时,poi不能读取修定状态为“最终状态”的数据,而是读取了所有修定内容,如下图所示:文本读取内容:正确内......
  • 第4章SpringMVC核心技术2异常处理
    第4章SpringMVC核心技术2异常处理SpringMVC框架处理异常的常用方式:使用@ExceptionHandler注解处理异常。项目结构如下:2.1@ExceptionHandler注解使用注解@Exce......
  • Java新特性(2):Java 10以后
    您好,我是湘王,这是我的51CTO博客,欢迎您来,欢迎您再来~虽然到目前为止Java的版本更新还没有什么惊天动地的改变,但总是会冒出一些有趣的小玩意。前面列举了Java9和Java10的一些特......
  • Mybatis出现Caused by: net.sf.jsqlparser.parser.ParseException: ....异常
    今天在开发项目中遇到了一个奇怪的异常,记录一下把!异常信息如下(截取了主要的部分)Causedby:net.sf.jsqlparser.parser.ParseException:Encountered""TOP""top""at......