网站首页 > 技术文章 正文
你在Java中使用过异常作为控制流吗?你也许不应该这么做。下面就是原因。
Java是一种通用的编程语言,有很多解决某个问题的方法。然而,有一些最佳实践需要遵循,也有一些坏的实践仍然普遍使用。
这些常见的错误实践之一是使用异常作为控制流。这应该避免,原因有二:它降低了代码作为单位时间响应的性能,并使代码可读性降低。
让我们首先通过查看下面的示例代码来了解如何使用异常作为控制流。代码的商业案例是:
public static int findAge(String name) { try { String ageAsString = findUser(name); return ageAsString.length(); } catch (NameNotFoundException e) { return 0; } } private static String findUser(String name) { if(name==null) { throw new NameNotFoundException(); } return name; }
如果客户端为findAge方法提供非空名称,则返回名称的长度,但如果用户名为空,则findUser方法将抛出NameNotFoundException,在这种情况下,findAge方法将返回0。
一个人如何能毫无例外地重构这段代码?坦率地说,有多种方法可以做到这一点,但这里只提供其中一种。
public static int findAgeNoEx(String name) { String ageAsString = findUserNoEx(name); return ageAsString.length(); } private static String findUserNoEx(String name) { if(name==null) { return ""; } return name; }
为了找出异常对性能的影响,我编写了以下代码,这段代码调用了两个实现的10万次,可以看出异常在我的英特尔酷睿i7-3630QM CPU上花费了数千毫秒。
public class ControlFlowWithExceptionOrNot { public static class NameNotFoundException extends RuntimeException { private static final long serialVersionUID = 3L; } private static final int TRIAL = 10000000; public static void main(String[] args) throws InterruptedException { long start = System.currentTimeMillis(); for (int i = 0; i < TRIAL; i++) { findAgeNoEx(null); } System.out.println("Duration :" + (System.currentTimeMillis() - start)); long start2 = System.currentTimeMillis(); for (int i = 0; i < TRIAL; i++) { findAge(null); } System.out.println("Duration :" + (System.currentTimeMillis() - start2)); }; public static int findAge(String name) { try { String ageAsString = findUser(name); return ageAsString.length(); } catch (NameNotFoundException e) { return 0; } } private static String findUser(String name) { if (name == null) { throw new NameNotFoundException(); } return name; } public static int findAgeNoEx(String name) { String ageAsString = findUserNoEx(name); return ageAsString.length(); } private static String findUserNoEx(String name) { if (name == null) { return ""; } return name; } }
输出得出:
Duration :16 Duration :6212
如果我们从可读性的角度比较这两个findAge方法,毫无例外的一个是非常清晰的,无论findUser方法返回什么,都要取它的长度,我们确信findUser方法将返回一个字符串。但是,有一个例外是有点混乱:findUser方法的返回不清楚。它可能返回一个字符串,或者抛出一个异常,并且从方法的签名来看,它是不可见的。因此,函数式编程范式不欢迎异常。
最后,如果在出现真正的异常情况时使用异常,则会更好。如果对控制流使用异常,则可能会导致性能问题,并且代码的可读性可能会降低。
希望这个能帮助你。
另外,麻烦关注一下呗。
猜你喜欢
- 2024-09-21 Java并发编程:LongAdder | LongAccumulator 对比测试
- 2024-09-21 「Java技巧」优雅的统计程序的执行时间,别再用System.cur
- 2024-09-21 Flink SQL 知其所以然(九)| SQL 的时间语义
- 2024-09-21 ArrayList插入1000w条数据之后,我怀疑了jvm...
- 2024-09-21 《Java实战之内存模型》详解篇(java内存模型happens before)
- 2024-09-21 比反射更快!使用ASM获取class信息(ClassReader)
- 2024-09-21 了解Java线程优先级,更要知道对应操作系统的优先级,不然会踩坑
- 2024-09-21 让大学生写的一个计算时间的方法,有人看得出来是在做什么吗?这
- 2024-09-21 Java基础——Java多线程(Lock接口详解)
- 2024-09-21 JVM性能调优监控工具jps、jstack、jmap、jhat、jstat使用详解
- 1514℃桌面软件开发新体验!用 Blazor Hybrid 打造简洁高效的视频处理工具
- 569℃Dify工具使用全场景:dify-sandbox沙盒的原理(源码篇·第2期)
- 510℃MySQL service启动脚本浅析(r12笔记第59天)
- 486℃服务器异常重启,导致mysql启动失败,问题解决过程记录
- 485℃启用MySQL查询缓存(mysql8.0查询缓存)
- 467℃「赵强老师」MySQL的闪回(赵强iso是哪个大学毕业的)
- 446℃mysql服务怎么启动和关闭?(mysql服务怎么启动和关闭)
- 444℃MySQL server PID file could not be found!失败
- 最近发表
- 标签列表
-
- c++中::是什么意思 (83)
- 标签用于 (65)
- 主键只能有一个吗 (66)
- c#console.writeline不显示 (75)
- pythoncase语句 (81)
- es6includes (73)
- windowsscripthost (67)
- apt-getinstall-y (86)
- node_modules怎么生成 (76)
- c++int转char (75)
- static函数和普通函数 (76)
- el-date-picker开始日期早于结束日期 (70)
- js判断是否是json字符串 (67)
- checkout-b (67)
- c语言min函数头文件 (68)
- asynccallback (71)
- localstorage.removeitem (74)
- vector线程安全吗 (70)
- & (66)
- java (73)
- js数组插入 (83)
- mac安装java (72)
- eacces (67)
- 查看mysql是否启动 (70)
- 无效的列索引 (74)