5.1 异常分类
所有异常都是Throwable的子类,分为Error(致命异常)和Exception(非致命异常)。Exception又分为checked异常(受检异常)和unchecked异常(非受检异常)。
checked异常可以进一步细分为两类:
- 无能为力、引起注意型
- 力所能及、坦然处置型
unchecked异常是运行时异常,它们都继承自RuntimeException,可以进一步细分为三类:
- 可预测异常(Predicted Exception)
- 需捕捉异常(Caution Exception)
- 可透出异常(Ignored Exception)
5.2 try代码块
try-catch-finally是处理程序异常的三部曲。
finally是在return表达式运行后执行的,此时将要return的结果已经被暂存起来,待finally代码块执行结束后再将之前暂存的结果返回。
5.3 异常的抛与接
要使捕获的异常与被抛出的异常是完全匹配的,或者捕获的异常是被抛出异常的父类。
防止NPE一定是调用方的责任,需要调用方进行事先判断。
5.4 日志
5.4.1 日志规范
推荐的日志文件命名方式为:appName_logType_logName.log。其中,logType为日志类型,推荐分类有stats、monitor、visit等,logName为日志描述。
日志被分为五种不同的级别,按重要程度由低到高排序:
- DEBUG级别日志记录对调试程序有帮助的信息
- INFO级别日志用来记录程序运行现场,虽然此处并未发生错误,但是对排查其他错误具有指导意义
- WARN级别日志也可以用来记录程序运行现场,但是更偏向于表明此处有出现潜在错误的可能
- ERROR级别日志表明当前程序运行发生了错误,需要被关注。但是当前发生的错误,没有影响系统的继续运行
- FATAL级别日志表明当前程序运行出现了严重的错误事件,并且将会被导致应用程序中断
1、预先判断日志级别
对DEBUG、INFO级别的日志,必须使用条件输出或者使用占位符的方式打印。该约定综合考虑了程序的运行效率和日志打印需求。
2、避免无效日志打印
生产环境禁止输出DEBUG日志且有选择地输出INFO日志。
3、区别对待错误日志
WARN、ERROR都是与错误有关的日志级别,但不要一发生错误就笼统地输出ERROR级别日志。
4、保证日志内容完整
- 记录异常时一定要输出异常堆栈
- 日志中如果输出对象实例,要确保实例类重写了toString()方法
5.4.2 日志框架
日志框架分为三大部分,包括日志门面、日志适配器、日志库。
1、日志门面
门面设计模式只提供一套接口规范,自身不负责日志功能的实现,目的是让使用者不需要关注底层具体是哪个日志库来负责日志打印及具体的使用细节。
目前用得最广泛的日志门面有两种:slf4j和commons-logging。
2、日志库
它具体实现了日志的相关功能,主流的日志库有三个,分别是log4j、log-jdk、logback。
3、日志适配器
- 日志门面适配器
- 日志库适配器