java 异常处理

 

  异常处理是 Java 开发中的一个重要部分,是为了处理任何错误状况,比如资源不可访问,非法输入,空输入等等。

  这里我们将讨论一些关于异常处理的 Java 最佳实践。在我们讨论异常处理的最佳实践之前,先让我们了解下几个重要的概念,那就是什么是异常以及异常的分类。

 

什么是异常? 

  异常本质上是程序上的错误,包括程序逻辑错误和系统错误。

  异常简单来说,就是一个程序在执行期间发生的事件,它中断正在执行程序的正常指令流。软件开发过程中,很多情况都会导致异常的产生,例如对负数开平方根、对字符串做算术运算、操作数超出范围、数组下标越界等。

  

异常分类

  Java 把异常当作对象来处理,并定义一个基类 java.lang.Throwable 作为所有异常的超类。

  Java 包括三种类型的异常: 检查性异常(checked exceptions)、非检查性异常(unchecked Exceptions) 和错误(errors)。    

  • 检查性异常(checked exceptions) 是必须在方法的 throws 子句中声明的异常。检查性异常表示在正常系统操作期间可能发生的预期问题。 当你尝试通过网络或文件系统使用外部系统时,通常会发生这些异常。 大多数情况下,对检查性异常的正确响应应该是稍后重试,或者提示用户修改其输入。
  • 非检查性异常(unchecked Exceptions) 是不需要在throws子句中声明的异常。 由于程序错误,JVM并不会强制你处理它们,因为它们大多数是在运行时生成的。 它们扩展了 RuntimeException。 最常见的例子是 NullPointerException, 未经检查的异常可能不应该重试,正确的操作通常应该是什么都不做,并让它从你的方法和执行堆栈中出来。
  • 错误(errors) 是严重的运行时环境问题,肯定无法恢复。 例如 OutOfMemoryError,LinkageError 和 StackOverflowError,通常会让程序崩溃。

 

  所有不是 Runtime Exception 的异常,统称为 Checked Exception,又被称为检查性异常。这类异常的产生不是程序本身的问题,通常由外界因素造成的。为了预防这些异常产生时,造成程序的中断或得到不正确的结果,Java 要求编写可能产生这类异常的程序代码时,一定要去做异常的处理。

  Java 语言将派生于 RuntimeException 类或 Error 类的所有异常称为非检查性异常。

  Java 异常层次结构图如下图所示:

    

 

 

 

2. 优先明确的异常
  你抛出的异常越明确越好,永远记住,你的同事或者几个月之后的你,将会调用你的方法并且处理异常。

  因此需要保证提供给他们尽可能多的信息。这样你的 API 更容易被理解。你的方法的调用者能够更好的处理异常并且避免额外的检查。

  因此,总是尝试寻找最适合你的异常事件的类,例如,抛出一个 NumberFormatException 来替换一个 IllegalArgumentException 。避免抛出一个不明确的异常。

  public void doNotDoThis() throws Exception {
    ...
  }
  public void doThis() throws NumberFormatException {
    ...
  }

  【推荐】定义时区分unchecked / checked 异常,避免直接抛出new RuntimeException(),更不允许抛出Exception或者Throwable,应使用有业务含义的自定义异常。推荐业界已定义过的自定义异常,如:DAOException / ServiceException等。

  【参考】对于公司外的http/api开放接口必须使用“错误码”;

      应用内部推荐异常抛出;

      跨应用间RPC调用优先考虑使用Result方式,封装isSuccess()方法、“错误码”、“错误简短信息”。说明:关于RPC方法返回方式使用Result方式的理由:

      1)使用抛异常返回方式,调用方如果没有捕获到就会产生运行时错误。

      2)如果不加栈信息,只是new自定义异常,加入自己的理解的error message,对于调用端解决问题的帮助不会太多。如果加了栈信息,在频繁调用出错的情况下,数据序列化和传输的性能损耗也是问题。

  【参考】避免出现重复的代码(Don’t Repeat Yourself),即DRY原则。

  说明:随意复制和粘贴代码,必然会导致代码的重复,在以后需要修改时,需要修改所有的副本,容易遗漏。必要时抽取共性方法,或者抽象公共类,甚至是组件化。 

posted on   快跑的小鸡  阅读(58)  评论(0编辑  收藏  举报

相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)
点击右上角即可分享
微信分享提示