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


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

    本文是处理 Java 异常的最佳实践。

    Java 中的异常处理并不是一件容易的事,因为新手很难知道应该去抛出或者处理哪些 Java 异常,资深的开发人员

    也会花费很长时间去确认哪些异常应该抛出、哪些异常应该处理。

    如果你是一个新手,那你很可能会对Java 异常处理中出现的各种情况感到迷惑和不解。

    本文展示了十个处理Java 异常的重要方法。异常,是指程序执行期间发生的异常情况。下面让我们一起来讨论一

    下处理 Java 异常的最佳实践。

    1、永远不要在 catch 块中吞掉异常

    catch (NoSuchMethodException e) {
       return null;
    }
    
    • 1
    • 2
    • 3

    如果你不了解失败的真正原因,那你就没有办法阻止这种失败的再次发生。

    如果不处理异常,直接返回 ”null” 。这样它就会吞掉异常,而你也就无法了解到为什么会失败,那么这个错误会一

    直存在,失败也会再次发生。

    2、声明式的抛出特定异常

    public void foo() throws Exception {  // 错误的方式
    }
    
    • 1
    • 2

    如果代码中需要抛出异常,那一定不要使用上述代码。

    Exception 是所有异常的父类,它会将其他抛出的异常都进行覆盖,异常信息也不够具体,从而无法对于特定的异

    常进行处理。如果需要抛出很多的异常,我们就要去声明可以由方法抛出的特定异常,这样才可以更好的去针对某

    个异常进行处理。

    public void foo() throws SpecificException1, SpecificException2 { // 正确的方式
    }
    
    • 1
    • 2

    3、不要捕获所有异常,而是捕获特定的子类

    try {
      someMethod();
    } 
    catch (Exception e) {
    	LOGGER.error("method has failed", e);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果按照上述代码捕获异常,用户调用方法产生的新异常都会包含在其中,那开发人员就没办法对特定的新异常进

    行处理。

    一旦有用户调用方法出现了特定的新异常,那永远也发现不了是哪儿的问题、无法进行修复。代码中如果一直存在

    没有修复的问题,那运行时就会再次崩溃。

    4、永远不要捕获任何 Throwable 类

    Throwable 的子类包含 java 错误,所以直接捕获 Throwable 会导致很严重的问题。

    Java 虚拟机不可能不发生错误、也无法控制发生什么样的错误、无法决定何时发生错误。所以在可能出现的最坏

    情况下,Java 虚拟机可能对 catch 子句中的任何错误都不进行处理。

    5、准确覆盖自定义异常中的异常,保证堆栈上下文不丢失

    catch (NoSuchMethodException e) {
    	throw new MyServiceException("Some information: " + e.getMessage());   //Incorrect way
    }
    
    • 1
    • 2
    • 3

    上述代码中,仅靠抛出异常的信息,无法进行堆栈的跟踪。可以修改为:

    catch (NoSuchMethodException e) {
      throw new MyServiceException("Some information: " , e);  
      //Correct way
    }
    
    • 1
    • 2
    • 3
    • 4

    6、不要又记录又抛出异常

    catch (NoSuchMethodException e) {
       LOGGER.error("Some information", e);
       throw e;
    }
    
    • 1
    • 2
    • 3
    • 4

    在上面代码中,看似很合理,但实际上,抛出和记录同一个异常会导致日志文件中输出多条日志消息,这样在开发

    人员想通过查看日志来解决问题的时候,就会带来很大的困难。

    7、不要在 finally 块中抛出异常

    try {
      someMethod();  //Throws exceptionOne
    }
    finally {
      cleanUp();    //如果最后也抛出一个异常,那么exceptionOne将永远丢失
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果可以保证 cleanUp() 永远不抛出异常,那上述代码就没问题。

    当 someMethod() 抛出了异常,并且在 finally 块中的 cleanUp() 也抛出了异常,那从 cleanUp() 中抛出的异常会

    把 someMethod() 抛出的异常覆盖,那第一个异常(someMethod() 抛出的,正确的原因)将永远丢失。

    8、只捕获你可以处理的异常

    catch (NoSuchMethodException e) {
    	throw e; //避免这样做,因为这样做没有什么用
    }
    
    • 1
    • 2
    • 3

    永远不要捕获你不能处理的异常是一个基本概念。

    在你可以处理某个异常的时候,再去捕获它。可以考虑在该异常中附加额外的信息对其进行处理。但如果你在

    catch 块中无法对它进行处理,那就不要捕获它。

    9、不要使用 printStackTrace() 语句

    在代码中使用 printStackTrace() ,它不会附加任何上下文信息,这样其他人完全不知道怎么去使用它,也就无法

    对这些堆栈进行跟踪。

    10、使用 finally 块对异常进行清理

    try {
      someMethod();  //Method 2
    } 
    finally {
      cleanUp();    // 这里做清理
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    如果你调用 someMethod() ,它抛出了异常,但是你不想对其处理,只想进行异常的清理,那就可以在 finally 块

    中进行清理,不要在 catch 块中执行。

    java 异常处理是必不可少的,并且有很多方法都可以很好的去处理这些异常。

    本文展示了处理Java 异常的最佳实践。处理Java异常对于初学者和资深的开发人员来说都相当困难,所以学会合

    理且正确的对其进行处理是非常重要的。

  • 相关阅读:
    mac安装jdk
    (二)详解观察者模式
    计算物理专题----随机游走实战
    springboot对接postgres
    LeetCode 1038.从二叉搜索树到更大和树
    引擎入门 | Unity UI简介–第2部分(3)
    SpringMvc执行流程
    C语言:指针的关系运算
    Python实现深度森林(Deep Forest)分类模型(deepforest分类算法)项目实战
    设计模式面试点汇总
  • 原文地址:https://blog.csdn.net/qq_30614345/article/details/132788240