这一讲的内容主要涉及异常和错误处理。这些年写了很多代码,但在异常设计方面有欠缺,一直感觉拿捏不准。何时定义异常,何时抛出异常,何时处理异常,都很难把握和权衡,感觉自己和周边的朋友,对异常的设计和处理,也是马马虎虎,大多数时候都是凑合着用。
知识点
- Exception是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理,从而恢复到正常状态。Error是指在正常情况下,不大可能出现的情况,绝大部分的Error都会导致程序处于非正常的、不可恢复的状态。所以不便于也不需要捕获。
- Exception分为可检查异常和不检查异常。
异常处理的原则
-
尽量不要捕获类似Exception这样的通用异常,而是应该捕获特定的异常。
理由:异常体现了作者的目的,我们有义务让自己的代码能够直观的体现出劲量多的信息。 -
不要生吞异常。
理由:可能会导致非常难诊断的诡异情况。 -
不要使用printStackTrace。
理由:在稍微复杂一点的生产系统中,标准输出或标准错误输出终端不是一个合适的输出选项,最好用定义的logger来输出异常信息,方便运维定位问题。 -
Throw early,catch late。
理由:非第一时间暴露出来问题,堆栈信息可能非常令人费解,往往需要相对复杂的定位。在发现问题时,第一时间抛出,能够更加清晰的反映问题。在更高层面,因为有了清晰的(业务)逻辑,往往会更加清楚合适的处理方式是什么。 -
考虑异常的性能损耗。
-
try-catch代码段会产生额外的性能开销。它往往会影响JVM对代码进行优化,尽量仅捕获有必要的代码段,不要一个大的try包住整段代码。不要用异常来控制代码流程。
-
Java每实例化一个Exception,都会对当时的栈进行快照,这是相对较重的操作。有些追求性能的底层库会尝试创建不进行栈快照的Exception。
-
-
当我们的服务出现反应变慢、吞吐量下降的时候,检查发生最频繁的Exception也是一种思路。
网友评论