try-with-resources: “use” extension function in Kotlin does not always work

时光毁灭记忆、已成空白 提交于 2019-12-01 03:18:30

Kotlin targets Java 6 at the moment, so its standard library does not use the AutoCloseable interface. The use function only supports the Java 6 Closeable interface. See the issue tracker for reference.

You can create a copy of the use function in your project and modify it to replace Closeable with 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()
        }
    }
}
Quy Tang

Kotlin 1.1+ has a standard library that targets Java 8 to support Closeable resource pattern - kotlin-stdlib-jre8

Gradle

compile "org.jetbrains.kotlin:kotlin-stdlib:1.1.1"
compile "org.jetbrains.kotlin:kotlin-stdlib-jre8:1.1.1"

Maven

<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib</artifactId>
    <version>1.1.1</version>
</dependency>
<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib-jre8</artifactId>
    <version>1.1.1</version>
</dependency>

Sample

val resource: AutoCloseable = getCloseableResource() 
resource.use { r -> //play with r }

For classes that do not support the "use" function, I have done the next homemade try-with-resources:

inline fun <T:AutoCloseable,R> trywr(closeable: T, block: (T) -> R): R {
    try {
        return block(closeable);
    } finally {
        closeable.close()
    }
}

Then you can use it the next way:

fun countEvents(sc: EventSearchCriteria?): Long {
    return trywr(connection.prepareStatement("SELECT COUNT(*) FROM event")) {
        var rs = it.executeQuery()
        rs.next()
        rs.getLong(1)
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!