前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java 中的Exception 有什么用?

Java 中的Exception 有什么用?

作者头像
ObjectiveSQL
修改2020-10-26 12:11:55
9990
修改2020-10-26 12:11:55
举报
文章被收录于专栏:ObjectiveSQL

Exception 的作用,这个问题是一个开放性的问题,没有标准的答案,不同经历的人可能会有不同的答案,也就是说经历过惨痛的经历后,才会对Java Exception 有深刻的认识,单纯理论学习,按部就班的按所谓的规范使用,无法准确的表达出Java Exception 的内在逻辑。

Exception 含义

Exception,顾名思义,代表着程序运行的过程中出现一种不正常的状态,需要中止程序的持续运行,同时又能快速的发现程序为什么会出现错,通过异常的信息能够快速定位,所以异常需要提供错误的上下文的状态信息,尤其是应用系统自身抛出的异常,需要将上下文状态尽可能多的输出,有助于排查和定位。Java 中的NullPointerException 对外提供的信息极少,所以应用系统应该尽可能catch 这类异常,包装为信息量更加丰富的异常抛出。

Exception 也是一种程序逻辑控制的方式,是程序健壮性的一种表现。其实,大都数异常,程序都应该有一定的相应的处理逻辑,例如,ArrayIndexOutOfBoundsException,这类异常在编码过程中应该能够被预见,并需要做出现相应的逻辑控制,有经验的程序员,在编码的过程中就已经考虑到各种异常的情况,待整个系统上线后,出现的问题相对较少,而普通的程序员往往只保证程序在Happy Case 时能够正常运行,却忽略了各种异常情况,往往是在出现问题后进行补救,导致程序在反复补救后,逻辑混乱,这也就是很多项目早期的代码质量高,经过一段时间后,代码惨不忍睹的根源。

Exception 的处理方式

什么时候需要catch Exception?什么时候需要throw 呢?这也是不会有标准答案的过程,Java 本身也没有给出标准答案,也没有指导原则。但经过无数次实践的经验后,你就能体会对异常的不同处理方式,对系统逻辑的稳定性性有着截然不同的影响,往往出现很诡异的Bug时,同时可参考的日志或其它关键丢失,导致故障不能及时解决,才会发现关键的位置异常被人为的隐藏是多么愚蠢的行为。

我在使用一个开源的框架时,时常会发现重要的异常信息被隐藏,导致花费大量的时间去跟踪代码。异常在什么时候需要throw,什么时候需要catch,原则其实很简单:

  1. 异常在能够完全掌控的情况下,而且也有明确的逻辑处理时,需要catch,并进行相应的处理。同时,也需要关注外部程序是否需要感知异常,如果需要,则封装新的异常后重新throw;
  2. 无法决定处理逻辑的情况下,需要将所有异常throw,让外部程序决定处理逻辑。同时,针对内部的信息含量较少的Runtime 型的异常,需要额外封装,避免在同一行代码中,无法确定哪一个对象为null。

Exception 定义

什么时候定义Exception 同样是没有任何指导原则,不同的技术框架中对异常定义的方式和方法都不太一样,毕竟每个应用系统的逻辑结构和复杂度都不太一定,我根据自身的经验整理了两个指导原则:

  1. 程序需要中止,自身又无法完整的处理逻辑转折,只能由外部调用者根据异常的信息,作为合理的逻辑处理,例如:数据采集时,出现了非法的数据或字符串,采集程序是无法判断逻辑转折后,就如何处理,同时又需要明确区分非常数据,甚至需要定义出错误的类型,由外部程序决定是忽略还是终止执行,在这种情况下需要定义明确的异常,用于标识错误的类型。
  2. 内部程序处理过程中出现太多异常,并且这类异常具有共同的特性(例如:ClassNotFountException, NoSuchMehtodException 等),不需要外部程序对这类异常分别处理时,需要定义一个异常用于包装内部异常,提升代码的可读性。
  3. 错误信息的补充,例如上文所提到的NullPointerException,应用系统程序需要为此异常补充更完整的信息,便于外部程序或日志系统提供足够的信息,便于故障的解决;

Exception 和 RuntimeException 有什么区别,在什么场景下定义,也是一个仁者见仁,智者见智的问题,Java 没有任何指导建议,按我个人的判断,JDK中也有很多的定义也不是特别合理,例如:IndexOutOfBoundsException 应该是一个Exception, JDK 却定义为RuntimeExcption 这类错误需要明确的提醒外部程序对数组进行逻辑限制,很多应用系统在总是在出现错误后,才能主动Cache 这类异常;然而像 ClassNotFoundException 这类异常在极少数状态下才会进行逻辑处理JDK 却定义为Exception 导致很多反射类的项目的处理逻辑变得复杂,NullPointerException 也是经常出现的,但定义为RuntimeException 是合理的,可能因为JDK 程序从逻辑上根本无法捕捉NullPointerException,应该是在JVM 执行过程中才能够进行逻辑判断,具体并未研究。

经过上面的两个示例也很容易看出Exception 和RuntimeException 有什么区别,JDK 的设计应该从外部程序使用的角度进行异常设计,由于外部程序导致的异常,并且外部程序应当有逻辑处理异常状态,这类异常理应定义为Exception,而其它由于JVM 在编码期无法判断,也无法从语法层面提供解释的Exception 应该定义为RuntimeException。

结论

针对Java 异常的解读是我个人的见解,就像古诗词一样,不同人有不同的解读,相信JDK 的设计者也无法给 Java Exception 一个明确的解释和原则,只能靠历史经验的积累和不断的错误中,逐形成相对完整的理论,供后人学习。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Exception 含义
  • Exception 的处理方式
  • Exception 定义
  • 结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档