Groovy 异常处理:try-catch-finally
在 Groovy 中编写健壮的程序,必须正确处理运行时可能出现的错误。Groovy 继承了 Java 的异常处理机制,并在此基础上做了简化和增强。使用 try-catch-finally 结构,你可以捕获异常、执行清理操作,并确保程序不会因未处理的错误而崩溃。
理解异常的基本概念
异常 是程序运行过程中发生的意外事件,比如文件不存在、网络中断或除零错误。Groovy 将异常分为两类:
- 受检异常(Checked Exception):编译器强制要求处理的异常(如
IOException),但在 Groovy 中通常可忽略,因为 Groovy 默认将所有异常视为非受检。 - 非受检异常(Unchecked Exception):继承自
RuntimeException的异常(如NullPointerException),不需要显式声明或捕获,但建议处理以提升稳定性。
Groovy 允许你像写脚本一样省略异常声明,但仍可通过 try-catch-finally 主动控制错误流。
编写基础的 try-catch 块
包裹可能出错的代码 在 try 块中,并用 catch 捕获特定类型的异常。
-
创建 一个包含潜在风险操作的代码块,例如读取文件:
try { new File("nonexistent.txt").text } catch (FileNotFoundException e) { println "文件没找到:${e.message}" } ``` 2. **捕获多种异常** 可以使用多个 `catch` 子句,按从具体到一般的顺序排列: ```groovy try { // 可能抛出多种异常的操作 def num = Integer.parseInt("abc") } catch (NumberFormatException e) { println "数字格式错误" } catch (Exception e) { println "其他错误:${e.class.simpleName}" } -
省略异常类型(Groovy 特有):如果你只关心是否出错而不关心具体类型,可直接写
catch (e):try { throw new RuntimeException("测试异常") } catch (e) { println "捕获到异常:${e.message}" } ``` --- ## 使用 finally 执行清理操作 无论是否发生异常,`finally` 块中的代码**总会执行**,适合用于释放资源(如关闭文件、数据库连接)。 1. **打开文件后确保关闭**: ```groovy def file = null try { file = new File("data.txt") println file.text } catch (IOException e) { println "读取失败:${e.message}" } finally { if (file?.exists()) { // 虽然 Groovy 的 File 不需要显式 close,但对流类资源很重要 println "清理完成" } } -
结合资源自动管理(推荐替代方案):Groovy 支持
withCloseable方法,可自动关闭实现了Closeable接口的对象:new FileInputStream("input.txt").withCloseable { stream -> // 使用 stream 处理数据 println stream.available() } // 自动调用 close()
高级技巧:异常传播与重新抛出
有时你需要捕获异常做日志记录,再让异常继续向上层传递。
- 记录日志后重新抛出:
try { riskyOperation() } catch (Exception e) { println "记录错误日志:${e.message}" throw e // 重新抛出原异常 } ``` 2. **包装为自定义异常** 提供更清晰的上下文: ```groovy try { connectToDatabase() } catch (SQLException e) { throw new RuntimeException("数据库连接失败,请检查配置", e) } ``` --- ## 常见陷阱与最佳实践 避免以下错误可大幅提升代码可靠性: | 问题 | 正确做法 | | :--- | :--- | | 空 `catch` 块(吞掉异常) | **至少记录日志**,如 `println e` 或使用日志框架 | | 捕获过于宽泛的 `Exception` | **优先捕获具体异常类型**,避免掩盖真正的问题 | | 在 `finally` 中抛出新异常 | **避免在 `finally` 中抛异常**,否则会覆盖原始异常 | 1. **不要忽略异常**: ```groovy // 错误示例 try { doSomething() } catch (Exception ignored) {} // 危险!问题被隐藏 // 正确做法 try { doSomething() } catch (Exception e) { log.error("操作失败", e) } ``` 2. **利用 Groovy 的安全操作符减少异常**:使用 `?.` 和 `?:` 可避免 `NullPointerException`: ```groovy def user = getUser() def name = user?.name ?: "匿名用户" // 安全访问属性 ``` --- ## 实战:完整文件读取示例 下面是一个兼顾健壮性与简洁性的文件读取函数: ```groovy def readFileSafely(String path) { def content = "" try { content = new File(path).text println "成功读取 ${path},共 ${content.size()} 字符" } catch (FileNotFoundException e) { println "❌ 文件不存在:${path}" } catch (SecurityException e) { println "🔒 权限不足,无法读取 ${path}" } catch (IOException e) { println "⚙️ 读取时发生 I/O 错误:${e.message}" } finally { println "—— 文件操作结束 ——" } return content }
// 调用示例
readFileSafely("example.txt")

暂无评论,快来抢沙发吧!