如何在Kotlin同时捕获许多例外

Ant*_*t20 58 kotlin

try { 

} catch (ex: MyException1, MyException2 ) {
    logger.warn("", ex)
}
Run Code Online (Sandbox Code Playgroud)

要么

try { 

} catch (ex: MyException1 | MyException2 ) {
    logger.warn("", ex)
}
Run Code Online (Sandbox Code Playgroud)

结果,编译错误:Unresolved reference: MyException2.

如何在Kotlin上同时捕获许多例外?

mie*_*sol 65

更新:如果您希望此功能登陆Kotlin,请投票支持以下问题KT-7128.谢谢@Cristan

根据此主题,此时不支持此功能.

abreslav - JetBrains队

目前还没有,但它已经摆在桌面上了

你可以模仿多捕获:

try {
    // do some work
} catch (ex: Exception) {
    when(ex) {
        is IllegalAccessException, is IndexOutOfBoundsException -> {
            // handle those above
        }
        else -> throw ex
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 即使你抛开优雅和丑陋的论点,在这种情况下,Kotlin(声称简洁)实际上是 Java 的 2 倍冗长 (3认同)
  • 我在这里复制`pdvrieze`回复:`这当然有效,但效率稍低,因为捕获的异常对jvm是显式的(因此不会捕获并重新抛出未处理的异常,这将是您的解决方案的必然结果)` (2认同)
  • @IARI `else` 子句重新抛出 _unwanted_ 异常。 (2认同)
  • @IARI [保留原始堆栈跟踪](/sf/ask/76826921/) (2认同)
  • 这会被 Detekt 标记,因为您捕获的异常太普遍了 ;-) (2认同)

Aro*_*Aro 9

补充一下miensol的答案:虽然 Kotlin 中的 multi-catch 尚不支持,但还有更多的替代方案需要提及。

除了try-catch-when,您还可以实现一种方法来模拟多捕获。这是一种选择:

fun (() -> Unit).catch(vararg exceptions: KClass<out Throwable>, catchBlock: (Throwable) -> Unit) {
    try { 
        this() 
    } catch (e: Throwable) {
        if (e::class in exceptions) catchBlock(e) else throw e
    }
}
Run Code Online (Sandbox Code Playgroud)

使用它看起来像:

fun main(args: Array<String>) {
    // ...
    {
        println("Hello") // some code that could throw an exception

    }.catch(IOException::class, IllegalAccessException::class) {
        // Handle the exception
    }
}
Run Code Online (Sandbox Code Playgroud)

您将需要使用函数来生成 lambda,而不是使用如上所示的原始 lambda(否则您将很快遇到“MANY_LAMBDA_EXPRESSION_ARGUMENTS”和其他问题)。类似的东西fun attempt(block: () -> Unit) = block会起作用。

当然,您可能希望链接对象而不是 lambdas 来更优雅地组合您的逻辑或表现得与普通的旧 try-catch 不同。

如果您要添加一些专业化,我只会建议在miensol 上使用这种方法。对于简单的多捕获用途,when表达式是最简单的解决方案。