java - try-with-resources:Kotlin 中的 "use"扩展功能并不总是有效

标签 java kotlin try-with-resources

我在表达 Java 的 try-with-resources 时遇到了一些麻烦。在 Kotlin 中构建。在我的理解中,作为 AutoClosable 实例的每个表达式都应该提供 use 扩展函数。

这是一个完整的例子:

import java.io.BufferedReader;
import java.io.FileReader;

import org.openrdf.query.TupleQuery;
import org.openrdf.query.TupleQueryResult;

public class Test {

    static String foo(String path) throws Throwable {
        try (BufferedReader r =
           new BufferedReader(new FileReader(path))) {
          return "";
        }
    }

    static String bar(TupleQuery query) throws Throwable {
        try (TupleQueryResult r = query.evaluate()) {
          return "";
        }
    }
}

Java-to-Kotlin 转换器创建以下输出:

import java.io.BufferedReader
import java.io.FileReader

import org.openrdf.query.TupleQuery
import org.openrdf.query.TupleQueryResult

object Test {

    @Throws(Throwable::class)
    internal fun foo(path: String): String {
        BufferedReader(FileReader(path)).use { r -> return "" }
    }

    @Throws(Throwable::class)
    internal fun bar(query: TupleQuery): String {
        query.evaluate().use { r -> return "" } // ERROR
    }
}

foo 工作正常,但 bar 中的代码无法编译:

Error:(16, 26) Kotlin: Unresolved reference.
None of the following candidates is applicable
because of receiver type mismatch: 
public inline fun <T : java.io.Closeable, R>
???.use(block: (???) -> ???): ??? defined in kotlin.io

query.evaluate() 来自 Sesame并实现 AutoClosable。是 Kotlin 的错误,还是有原因导致它不起作用?


我将 IDEA 15.0.3 与 Kotlin 1.0.0-beta-4584-IJ143-12 和以下 sasame-runtime 版本一起使用:

<groupId>org.openrdf.sesame</groupId>
<artifactId>sesame-runtime</artifactId>
<version>4.0.2</version>

最佳答案

Kotlin 目前以 Java 6 为目标,因此其标准库不使用 AutoCloseable 接口(interface)。 use 函数仅支持 Java 6 Closeable 接口(interface)。见 the issue tracker供引用。

您可以在项目中创建 use 函数的副本并修改它以将 Closeable 替换为 AutoCloseable:

public inline fun <T : AutoCloseable, R> T.use(block: (T) -> R): R {
    var closed = false
    try {
        return block(this)
    } catch (e: Exception) {
        closed = true
        try {
            close()
        } catch (closeException: Exception) {
            e.addSuppressed(closeException)
        }
        throw e
    } finally {
        if (!closed) {
            close()
        }
    }
}

关于java - try-with-resources:Kotlin 中的 "use"扩展功能并不总是有效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35136715/

相关文章:

java - 有没有办法只接受 JTextField 中的数值?

java - 在 IntelliJ 中的表单构建中自动生成表单组件的代码

android - 未为 Http 状态代码 400 调用 Kotlin RxJava2 onError

java - Java 1.6 中的 Try-with-resources 等价物

java - JNI(Java 和 C++)在 Ubuntu 11.10 上使用 Eclipse

Windows 中的 JavaFx 内存泄漏,但 mac osx 中没有

android - 我可以使用 Kotlin 合成扩展让两个 xml 布局使用相同的 View 吗?

java - 如何通过改造获取 POJO 和原始响应字符串?

java - 为什么 StAX 类没有在 Java 7 中针对 ARM 进行改造

java - 对 CloseableHttpClient 使用 try-with-resource block 是否也会关闭返回的 CloseableHttpResponse?