软件工程领域的大师级人物 Robert C. Martin在《Clean Code》中讲道:
错误处理是十分必要的,但是如果对错误处理使用不当则会让代码变得十分臃> > 肿,让阅读者看不清代码的逻辑,更严重的是,这也会让程序变得十分脆弱。
使用Exception
而不是返回码
返回码是一个历史遗留问题,在以前的没有
Exception
的语言(比如c语言)中,它是有效且必要的,但是在有Exception
的语言中使用返回码是没有任何益处的。
对于使用返回码的函数,调用者在得到调用结果(这里是返回码)之后要立即去验证返回码,这对于代码的可读性和结构的合理性都是极大的挑战,使用「异常处理」能让业务逻辑和错误处理在代码结构上分离,代码的结构和逻辑会更清晰。
========华丽的分割线========
使用异常来取代层层传参来解决状态传递问题,的确是一种进步,但如果滥用,把本该使用返回值传参的地方也使用异常,得不偿失了,特别是TPS要求比较高的接口。
现在我们就来实测下这种抛异常的策略,是否会影响性能:
代码:
/**
* 相同条件下,同样的业务逻辑和IO下,比较抛异常和不抛异常场景下,
* 在性能上有什么区别
*/
@Test
public void givenTwoScenario_whenOneHasExceptionAndAnotherNot_thenGetTheElapsedTime() {
StopWatch stopWatch = new StopWatch("OneHasExceptionAndAnotherNot");
stopWatch.start("hasNoException");
int length = 1000000;
for (int i = 0; i < length; i++) {
doBizHasNoException(String.valueOf(i));
}
stopWatch.stop();
stopWatch.start("hasException");
for (int i = 0; i < length; i++) {
doBizHasException(String.valueOf(i));
}
stopWatch.stop();
log.info("{}", stopWatch.prettyPrint());
}
/**
* 没有抛异常的场景【也打印个日志】
*
* @param i
*/
public void doBizHasNoException(String i) {
try {
log.info("result:{}", i);
} catch (Exception e) {
log.warn("{}", e.getMessage());
}
}
/**
* 抛异常的场景【打印个日志】
*
* @param i
*/
public void doBizHasException(String i) {
try {
throw new IllegalArgumentException(i);
} catch (Exception e) {
log.warn("{}", e.getMessage());
}
}
实际执行效果:
10:19:26.327 [main] INFO com.tangcheng.learning.syntax.PerformanceAnalysisUseExceptionTest - StopWatch 'OneHasExceptionAndAnotherNot': running time (millis) = 17315
-----------------------------------------
ms % Task name
-----------------------------------------
05510 032% hasNoException
11805 068% hasException
可以看到,抛异常场景下,会更耗性能。
这个结论是不是很逆天,很不可思议。
当时也觉得百思不得其解,后来偶然在《极客时间》上听了 郑雨迪 讲的《深入拆解Java虚拟机》,感觉豁然开朗,那就不班门弄斧了,直接看看大佬来自jvm的视角:
异常实例的构造十分昂贵。这是由于在构造异常实例时,Java虚拟机便需要生成该异常的栈轨迹(stack trace)。该操作会逐一访问当前线程的Java栈帧,并且记录下各种调试信息,包括栈桢所指向方法的名字,方法所在的类名、文件名,以及在代码中的第几行触发该异常。
上面的文本不能copy,敲着比较费劲,那就直接截图了啊:
![](https://img.haomeiwen.com/i6086860/6c2ecc141d643f7a.jpg)
评论永远有经典:
![](https://img.haomeiwen.com/i6086860/69080ecaf253a28d.jpg)
![](https://img.haomeiwen.com/i6086860/22a29faed99eb7d2.jpg)
![](https://img.haomeiwen.com/i6086860/bba05612ff21635a.jpg)
![](https://img.haomeiwen.com/i6086860/dfe6f1936b48b226.jpg)
这个栏目提供有试读,有兴趣的同学,来扫这个二维码:
![](https://img.haomeiwen.com/i6086860/39f092474ce53c38.jpg)
网友评论