kotlin - Kotlin 中的 throw 语句

标签 kotlin exception

在像这样的 Kotlin 表达式中

fun main() {
    throw throw throw RuntimeException("boom")
}

fun main() {
    throw throw return
}

语法正确

我理解它背后的想法,但我想知道为什么在写这种废话时没有警告(至少在 Itellij 中)。

最佳答案

这在 KT-22621 "throw throw Exception()": False negative UNREACHABLE_CODE warning 中被报告为一个小问题.需要注意的是,如果你加上括号,无法访问的代码会被警告:

throw (throw Exception())
// or
throw (return)

此外,return throws Exception() 也会给出警告。

不幸的是,4 年后它仍然是一个悬而未决的问题。

看了一点Kotlin的源码,我觉得这是无意的。让我们考虑 ControlFlowProcessor.kt,visitThrowExpression :

override fun visitThrowExpression(expression: KtThrowExpression) {
    mark(expression)

    generateJumpsToCatchAndFinally()

    val thrownExpression = expression.thrownExpression ?: return
    generateInstructions(thrownExpression)

    val thrownValue = builder.getBoundValue(thrownExpression) ?: return
    builder.throwException(expression, thrownValue)
}

考虑 throw throw Exception()。当访问第一个 throw 时,generateInstructions(thrownExpression) 生成与 throw Exception() 对应的 CFG 部分。这会导致访问第二个 throw,为 throw Exception() 生成正确的 CFG。

builder.getValue(thrownExpression) 被调用时,问题就来了。这从表示抛出值的 CFG 构建器获取一个 PseudoValue。但是,(我怀疑)这会返回 nil 并且 builder.throwException 不会被调用。这是因为在为 throw Exception() 构建 CFG 时,没有绑定(bind)任何值。将此与 visitParenthesizedExpression 中发生的情况进行比较,或 visitCallExpression,但您需要更深入地追踪。

这不会对控制流分析产生太大影响,因为为 throw Exception() 生成的 CFG 部分是正确的。 CFG 确实最终缺少一个节点来表示外部throw,这就是builder.throwException。会添加。该节点将被标记为不可访问并发出警告,但该节点甚至不存在,因此没有警告。

关于kotlin - Kotlin 中的 throw 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70288747/

相关文章:

android - Glide 4.3.1 : how to use error()?

android - BottomAppBar 与 BottomNavigationDrawer 连接到 NavigationController

c++ - 在 Visual Studio 中使用 C++17 静态内联成员时的奇怪行为

java - 如何在java中有效地使用方法中的参数?

java - Play 中的 CConvertException!框架

debugging - 发生异常时程序在 gdb 下卡住

java - 更新安卓模块

kotlin - 如何在 Kotlin 中扩展枚举?

android - 当我按下onClick Android时按钮会缩小

python - Google Appengine 和 Python 异常