当前位置: 首页 > 知识库问答 >
问题:

我应该在静态编程语言中处理Closable.use{...}异常吗?

益银龙
2023-03-14

根据 Closable.use 的来源,如果发生错误,将引发异常。

public inline fun <T : Closeable?, R> T.use(block: (T) -> R): R {
    var exception: Throwable? = null
    try {
        return block(this)
    } catch (e: Throwable) {
        exception = e
        throw e
    } finally {
        when {
            apiVersionIsAtLeast(1, 1, 0) -> this.closeFinally(exception)
            this == null -> {}
            exception == null -> close()
            else ->
                try {
                    close()
                } catch (closeException: Throwable) {
                    // cause.addSuppressed(closeException) // ignored here
                }
        }
    }

Closable.use的大多数示例中,没有使用try-catch,如下所示。为什么不需要错误处理?它安全吗?

    BufferedReader(FileReader("test.file")).use { return it.readLine() }

共有2个答案

穆浩皛
2023-03-14

我们从Kotlin文档中可以看出< code>use函数的用途是什么:

在此资源上执行给定的块函数,然后无论是否抛出异常都正确关闭它。

如果块函数成功完成或引发异常,则此函数将正确关闭资源。您有责任处理阻止功能的结果。

如果抛出了异常,并且有办法处理它并继续执行代码,请使用try/catch。如果对此无能为力,控制应该传递给调用者,就没有必要使用try/catch。

谷梁鸣
2023-03-14

此行

 BufferedReader(FileReader("test.file")).use { return it.readLine() }

不安全。读取和关闭读取器都会引发IOExceptions,io exceptions不是RuntimeExceptions(由编程错误引起)。这意味着不捕捉它们会使你的应用程序暴露在你控制之外的东西的冲击之下。

由于Kotlin没有检查过的异常,编译器不会就此警告您。要安全地执行此操作,需要将其包装在try/catch中。如果要以不同于关闭错误的方式处理读取错误,则需要使用内部和外部try/catch语句:

try { 
    BufferedReader(FileReader("test.file")).use { 
        try {
            return it.readLine()
        catch (e: IOException) {
            println("Failed to read line")
        }
    }
} catch (e: IOException) {
    println("Failed to close reader")
}

或者包装整个东西并提取任何隐藏的异常,但是区分它们是很麻烦的:

try {
    BufferedReader(FileReader("test.file")).use { return it.readLine() }
} catch (e: IOException) {
    val throwables = listOf(e, *e.suppressed)
    for (throwable in throwables)
        println(throwable.message)
}

但是在实践中,你可能不会对各种IOExceptions做出不同的反应,所以你可以把try/catch放在外面。

 类似资料:
  • 当结合使用SpringWebFlux和Kotlin协同程序时,我很难理解一个简单的RESTfulWS响应处理场景。假设我们在REST控制器中有一个简单的WS方法,该方法可能返回大量(数百万)响应“things”: 这正如人们所期望的那样:只要使用流媒体类型(例如“application/x-ndjson”),结果就会流式传输到客户端。在更复杂的服务调用中,也考虑了错误/警告的可能性,我希望返回以下

  • 我想知道为什么在下面的代码中没有捕捉到异常: 函数的调用方式如下: 但我还是遇到了一个导致应用程序崩溃的异常: 我想说try/catch块会捕获异常,但唉。。。 什么原因导致异常没有被捕获?我想说线程并不重要,因为我使用try/get块来处理线程中的异常。 在Laalto的回答之后,我更新了代码,如下所示(对于那些感兴趣的人):

  • 在Java中,程序员可以为JUnit测试用例指定预期的异常,如下所示: 在科特林我该怎么做?我尝试了两种语法变体,但都不起作用:

  • 暴露0.27.1是否能够翻译以下SQL语句? 下面是我尝试的内容,但不幸的是,子查询独立于查询的其余部分工作。 此外,如果可能的话,那么如何使用别名从ResultRow获取结果?在这个示例之后,解决方案似乎是将整个子查询存储在单个变量中,并使用一个alias()方法调用,但这看起来很难看。有没有更好的方法?

  • 我有以下问题:-创建了几个模块来实现类,并用-我的Android应用程序正在使用检索这些类。但是由于某种原因,没有在

  • 我试图用OkHttp和Cucumber在静态编程语言中设置一个Spring启动项目,并且在运行Cucumber任务时遇到以下错误。如何修复? 还有build gradle kts片段 我看到了这个错误https://github.com/square/okio/issues/647看起来可能是它,并修复了这个build.gradle,我如何将其翻译为kotlinbuild.gradle.kts?