美文网首页
Java异常最佳实践

Java异常最佳实践

作者: 烤玉米馒头 | 来源:发表于2018-07-14 17:02 被阅读0次

0. 异常体系

异常体系
  • Throwable
    java所有的异常和错误类都继承自Throwable类,其有两个直接子类:ErrorException
  • Error
    其中Error是系统性异常,是无法恢复的,也不应该捕获的,日常代码不会使用到的,比如内存溢出错误OutOfMemoryError
  • Exception
    Exception的子类分为两类:RuntimeExceptionRuntimeException子类,Exception的其他子类,分别称为受检异常和非受检异常。
  • checked exception
    受检异常是Exception类和直接或间接继承自Exception的子类,但不继承RuntimeException
    受检异常是必须要处理的异常,也就是必须要try-catch捕获或者声明throws抛出的异常,如:

ClassNotFoundException
IOException
SQLException

  • unchecked exception
    非受检异常,也成为运行时异常,直接或间接继承自RuntimeException,有别于受检异常的一个重要的特定是,非受检异常不需要try-catch捕获或者throws声明来处理,如:

NullPointerException
IllegalArgumentException
NumberFormatException
IndexOutOfBoundsException
IllegalStateException

1. 使用非受检异常

由于调用受有检异常声明的api,必须要捕获或者声明throws,若throws,则更上层的调用者还是一样要处理,所以如果能确定需要调用者意识到采取措施,并且能有恢复方案才考虑使用受检异常,否则如果都不确定,就应该使用非受检异常。

2. 使用标准异常

使用jdk标准的异常,因为一个异常类主要的信息类名,而标准异常是大家熟知的,能到达见名知意,在排除问题时能很好的定位。

3. 自定义异常

如果非要自定义异常,则可以按业务分层设计对应的异常体系,比如WEB应用,有view、controller、service、dao层,可以设计对应的异常类,并建立对应message和code:

BaseException extends RuntimeException // 统一业务处理逻辑,子类只有类名不同
BussinessException extends BaseException
ViewException extends BaseException
ControllerException extends BaseException
ServiceException extends BaseException
DAOException extends BaseException

4. 没有异常恢复方案时不要捕获异常

如果对异常情况没有恢复方案,则不要捕获异常并抛出,因为捕获并抛出异常性能也会影响,并且输出大量重复的异常信息,这样不便于定位错误。

5. 异常转义不要抛弃原始异常

比如DAO层捕获IOException时,可以转义为DAOException异常,但不能抛弃到原始的IOException

6. 不要抛弃异常

如果已有恢复方案,则可以考虑吃掉异常,并转到恢复方案,同时记录异常信息,比如在使用redis时,redis连接失败,则可以转调DB获取数据。

    public void discardException() {
        try {
            FileInputStream input = new FileInputStream("data.txt");
        }
        catch (IOException e) {
             // 不应该抛弃异常, 除非已经确定有恢复方案
            e.printStackTrace();
        }
    }

7. 使用和捕获具体异常

8. 不要使用异常来控制程序流程

9. 输出详细的异常信息

捕获异常后,应该输出完整的上下文信息,比如请求远程接口失败,则可以将URL、入参等相关信息都输出,以便定位排查。

10. 统一规范的输出异常信息

11. 使用finally关闭资源或者try-catch-resouces

我们在使用IO、数据库链接需要在finally块或者try-catch-resources语句关闭资源。
但如果使用try-catch-resouces语句时,若close资源异常,则会影响整体业务的,所以可以考虑使用finally块close资源,并且压制异常,如:

public class ReadFile {
   public void read(String filename) throws BaseException {
       FileInputStream input = null;
       IOException readException = null;
       try {
           input = new FileInputStream(filename);
       } catch (IOException ex) {
           readException = ex;
       } finally {
           if (input != null) {
               try {
                   input.close();
               } catch (IOException ex) {
                   if (readException == null) {
                       ex.printStackTrace(); // 打印异常
                   }else{
                       readException.addSuppressed(ex);
                   }
               }
           }
           if (readException != null) {
               throw new BaseException(readException);
           }
       }
   }
}

12. 区分异常和错误提示

当程序出现异常或者错误时,应该详细记录异常日志,以便排除,但这些日志不应直接展示给用户,展示给用户的应该是重新输入、输入的数据格式不对,如果是系统异常,可以提示网络异常。

相关文章

  • Java 最佳实践的经验

    Java 最佳实践的面试问题 包含 Java 中各个部分的最佳实践,如集合,字符串,IO,多线程,错误和异常处理,...

  • Java异常最佳实践

    0. 异常体系 Throwablejava所有的异常和错误类都继承自Throwable类,其有两个直接子类:Err...

  • Exception

    Java 中 9 个处理 Exception 的最佳实践 Java 中的异常和处理详解 如何优雅的设计 Java ...

  • Java异常处理最佳实践

    在 Java 中处理异常并不是一个简单的事情。不仅仅初学者很难理解,即使一些有经验的开发者也需要花费很多时间来思考...

  • Java异常处理最佳实践

    我们为什么要做异常处理 1、给请求端明确的操作指导。 2、正确记录系统异常时的完整场景,包括代码的调用过程、出错点...

  • Java 异常分析

    本文是对以下内容的分析: Java异常设计 Java 异常分类 Java异常可以告诉什么问题 Java异常处理最佳...

  • Java 字符串拼接效率分析及最佳实践

    转载请注明出处: Java 字符串拼接效率分析及最佳实践 本文来源于问题 Java字符串连接最佳实践? java连...

  • Java异常处理 10 个最佳实践

    异常处理是Java 开发中的一个重要部分。它是关乎每个应用的一个非功能性需求,是为了处理任何错误状况,比如资源不可...

  • Java程序员常犯的几类错误

    1.忽视异常 相信很多小伙伴在编程的过程中经常对异常置之不理。针对初学者和有经验的 Java 程序员,最佳实践仍是...

  • Spring Boot统一异常处理实践

    摘要: SpringBoot异常处理。 原文:Spring MVC/Boot 统一异常处理最佳实践 作者:赵俊 前...

网友评论

      本文标题:Java异常最佳实践

      本文链接:https://www.haomeiwen.com/subject/xgbspftx.html