Java 异常机制
Java中的异常处理可以提高系统的健壮性以及用户体验。Throwable是所有异常和错误的父类,其继承结构如下:
a) Unchecked Exception
非检查异常不要求程序员捕获,且可以由系统自动抛出, 如除法运算中除数为0时,程序自动抛出ArithmeticException的算术异常,而不用程序员手动抛出。RuntimeException表示代码本身存在BUG。
b) Checked Exception
检查异常强制要求程序员捕获异常,否则编译不通过,假如将 SQLException 定义为非检测异常,开发人员可能不会捕获处理异常。这样操作数据发生异常时,会导致严重的 Connection 不关闭、Transaction 不回滚、DB 中出现脏数据等情况。将SQLException 定义为检测异常,才会驱使开发人员去显式捕捉,并且在代码产生异常后清理资源。当然清理资源后,可以继续抛出非检测异常,阻止程序的执行。检测异常大多可以应用于工具类中。
Java提供的检查异常机制,使得调用时可以明确知道该函数必须用try-catch捕获,而不用查看源代码才知该函数中存在异常。
常见问题
1. 代码层次结构的污染
上面的代码中直接抛出了检查异常,从代码耦合角度上看,调用层需显示捕获。根据设计隔离原则,可以使用非检测异常进行封装,使得调用层可以不受该函数影响。
public Order getOrderById(Long id) throw SQLException { //根据 ID 查询数据库 } /* 改正后 */ public Order getOrderById(Long id) { try{ //根据 ID 查询数据库 }catch(SQLException e){ throw new RuntimeException(SQLErrorCode, e); //利用非检测异常封装检测异常,降低层次耦合 }finally{ //关闭连接,清理资源 } }
2. 将异常包含在循环语句块中
异常处理会占用系统资源,应该将try-catch语句块提取到循环外面。比如A类中有个方法a包含try-catch语句块, 而B类中循环调用a方法,这就发生了如下的问题。
for(int i=0; i<100; i++){ try{ }catch(Exception e){ //... } }
3. 异常打印问题
· 多层次打印问题,比如Dao层中打印了log, Service层中又打印一遍,这样不仅消耗系统性能,还使得日志更为混乱了。
· 异常打印信息中可以添加一些参数信息如orderId,便于追踪。
4. 利用 Exception 捕捉所有潜在的异常
如果try中可能抛出各种异常,只用一个Exception去捕捉异常,可能会丢失原始异常的有效信息。记录异常信息时,还可以使用errorCode记录状态,编译开发人员后期跟踪系统运行状态。
参考原文: http://www.codeceo.com/article/java-exception-misdirection.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix