网站首页 > java教程 正文
你在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-10-06 收藏!用了一个月整理java(理论,进阶,实战)附完整视频
- 2024-10-06 Java 是一种广泛使用的编程语言,具有以下特点
- 2024-10-06 5个用例帮你全面了解Java泛型应用
- 2024-10-06 Java 工程师相见恨晚的神兵利器和使用技巧
- 2024-10-06 Java主要的5个标准注解如何使用?(java主要的5个标准注解如何使用?怎么解决)
- 2024-10-06 7个维度+43条使用规范,带你彻底玩转Redis
- 2024-10-06 java的方法,方法的定义格式,方法的重载
你 发表评论:
欢迎- 最近发表
-
- 你真的会用 Java 中的线程池吗?多个企业级线程池工具类封装实践
- 线程池的实现原理、优点与风险、以及四种线程池实现
- Java线程池ThreadPoolExecutor实现原理剖析
- 深入分析线程池的实现原理(线程池是干嘛的)
- 一文搞懂JAVA线程池工作原理(java线程池的工作流程)
- Java线程池的工作原理(java线程池的实现原理)
- 5分钟读懂C#中TcpClient、TcpListener和Socket三个类的角色
- JVM对象的创建过程(jvm运行过程中创建的对象一般存放在方法区)
- 对象组成与Java内存模型JMM分析(java对象在内存中存储的结构)
- JVM对象内存分配详细过程(栈上分配->TLAB->老年代->Eden区)
- 标签列表
-
- java反编译工具 (77)
- java反射 (57)
- java接口 (61)
- java随机数 (63)
- java7下载 (59)
- java数据结构 (61)
- java 三目运算符 (65)
- java对象转map (63)
- Java继承 (69)
- java字符串替换 (60)
- 快速排序java (59)
- java并发编程 (58)
- java api文档 (60)
- centos安装java (57)
- java调用webservice接口 (61)
- java深拷贝 (61)
- 工厂模式java (59)
- java代理模式 (59)
- java.lang (57)
- java连接mysql数据库 (67)
- java重载 (68)
- java 循环语句 (66)
- java反序列化 (58)
- java时间函数 (60)
- java是值传递还是引用传递 (62)
本文暂时没有评论,来添加一个吧(●'◡'●)