1. 简介

程序运行过程中,若出现意料之外的情况,就会触发一个 异常(Exception)。像 Kotlin 和 Java 这类语言都内置了丰富的异常类,用于处理常见的错误场景。

但实际开发中,通用异常往往不够用。✅ 我们更需要的是能精准表达业务语义的 自定义异常类,以便更好地定位问题、提升代码可读性。本文将带你掌握在 Kotlin 中如何优雅地创建和使用自定义异常。

💡 为什么需要自定义异常?
想象一下日志里全是 IllegalArgumentException,你根本无法快速判断是参数为空、格式不对还是越界。而 InvalidUserInputException 就清晰得多。

2. 创建一个简单的自定义异常

最直接的方式,就是定义一个继承自 Exception 的类:

class MyCustomException(message: String) : Exception(message)

这样就得到了一个可以携带描述信息的异常类型。使用时也很直观:

throw MyCustomException("这是自定义异常的详细说明")

捕获方式与标准异常无异,使用 try-catch 即可:

try {
    throw MyCustomException("这是自定义异常的详细说明")
} catch (e: MyCustomException) {
    // 在这里处理异常
    println("捕获到自定义异常: ${e.message}")
}

📌 注意:捕获时需明确指定异常类型,避免用 catch (e: Exception) 吞掉所有异常,这属于反模式 ❌。

更多 Kotlin 异常处理细节,可参考之前的文章:Kotlin 异常处理详解

3. 创建功能完整的自定义异常

上面的例子虽然简单,但只覆盖了父类 Exception 的部分构造函数。⚠️ 实际上,Exception 提供了四个重载构造器:

class Exception {
    ...
    constructor()                                      // 无参
    constructor(message: String?)                     // 只有消息
    constructor(message: String?, cause: Throwable?)  // 消息 + 根源异常
    constructor(cause: Throwable?)                    // 只有根源异常
    ...
}

如果我们希望自定义异常具备同等能力,就必须全部实现:

class MyCustomException : Exception {
    constructor() : super()
    constructor(message: String) : super(message)
    constructor(message: String, cause: Throwable) : super(message, cause)
    constructor(cause: Throwable) : super(cause) 
}

✅ 如此一来,这个异常就能在任何标准 Exception 可用的上下文中无缝替换,灵活性大大增强。

4. 使用默认参数减少模板代码

第 3 节的做法虽然完整,但写起来略显啰嗦——四个构造函数全是模板代码。 Kotlin 的 默认参数(default arguments) 特性正好可以解决这个问题:

class CustomException(
    message: String? = null,
    cause: Throwable? = null
) : Exception(message, cause)

✅ 一行代码搞定!这个简洁版本等价于实现了全部四种构造方式:

  • CustomException() → 无参
  • CustomException("出错了") → 带消息
  • CustomException(cause = someException) → 带根源
  • CustomException("验证失败", someException) → 消息 + 根源

💡 踩坑提醒:
记得把参数声明为可空类型(String?, Throwable?),否则无法匹配原始构造函数的签名,会导致调用失败 ❌。

这种写法不仅代码更干净,维护成本也更低,推荐作为首选方案。

5. 总结

在 Kotlin 中创建自定义异常非常简单:

  • ✅ 基础需求:继承 Exception 并传入 message
  • ✅ 完整功能:通过默认参数一键支持所有构造方式,避免冗余代码

合理使用自定义异常,能让错误处理更精确、日志更清晰、调试更高效。

所有示例代码均已上传至 GitHub:https://github.com/Baeldung/kotlin-tutorials/tree/master/core-kotlin-modules/core-kotlin-6


原始标题:Create and Throw a Custom Exception With Kotlin