我自己针对 Kotlin 缺少资源尝试的解决方案
My own solution for Kotlin's try-with-resources absence
Kotlin 为 Closeable
对象提供了 use
函数,但他们似乎忘记考虑 AutoCloseable
(例如数据库准备语句)用于 try-with-resources full Java相当于.
我已经实施了下一个 "home-made" 解决方案:
inline fun <T:AutoCloseable,R> trywr(closeable: T, block: (T) -> R): R {
try {
return block(closeable);
} finally {
closeable.close()
}
}
那你就可以用下面的方法了:
fun countEvents(sc: EventSearchCriteria?): Long {
return trywr(connection.prepareStatement("SELECT COUNT(*) FROM event")) {
var rs = it.executeQuery()
rs.next()
rs.getLong(1)
}
}
我是 Kotlin 的新手,我想知道我自己的解决方案中是否遗漏了一些可以在生产环境中为我提供 problems/leakages 的重要内容。
您的实现可以正常工作,但它不同于标准的 try-with-resources 实现。如果你想让它像 Java 那样工作,你应该这样做:
inline fun <T : AutoCloseable, R> trywr(closeable: T, block: (T) -> R): R {
var currentThrowable: java.lang.Throwable? = null
try {
return block(closeable)
} catch (throwable: Throwable) {
currentThrowable = throwable as java.lang.Throwable
throw throwable
} finally {
if (currentThrowable != null) {
try {
closeable.close()
} catch (throwable: Throwable) {
currentThrowable.addSuppressed(throwable)
}
} else {
closeable.close()
}
}
}
更新:
由于 mfulton26 pointed out in his kotlin.Throwable
不包含 addSuppressed(Throwable)
方法,因此我们必须将 kotlin.Throwable
转换为 java.lang.Throwable
以使代码正常工作。
我想你想要的是 use()
定义在 Closable
.
自 Kotlin 1.1 起,.use
有一个 AutoCloseable
实现。
@SinceKotlin("1.1")
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
@kotlin.internal.InlineOnly
public inline fun <T : AutoCloseable?, R> T.use(block: (T) -> R): R {
var exception: Throwable? = null
try {
return block(this)
} catch (e: Throwable) {
exception = e
throw e
} finally {
this.closeFinally(exception)
}
}
复制自source
Kotlin 为 Closeable
对象提供了 use
函数,但他们似乎忘记考虑 AutoCloseable
(例如数据库准备语句)用于 try-with-resources full Java相当于.
我已经实施了下一个 "home-made" 解决方案:
inline fun <T:AutoCloseable,R> trywr(closeable: T, block: (T) -> R): R {
try {
return block(closeable);
} finally {
closeable.close()
}
}
那你就可以用下面的方法了:
fun countEvents(sc: EventSearchCriteria?): Long {
return trywr(connection.prepareStatement("SELECT COUNT(*) FROM event")) {
var rs = it.executeQuery()
rs.next()
rs.getLong(1)
}
}
我是 Kotlin 的新手,我想知道我自己的解决方案中是否遗漏了一些可以在生产环境中为我提供 problems/leakages 的重要内容。
您的实现可以正常工作,但它不同于标准的 try-with-resources 实现。如果你想让它像 Java 那样工作,你应该这样做:
inline fun <T : AutoCloseable, R> trywr(closeable: T, block: (T) -> R): R {
var currentThrowable: java.lang.Throwable? = null
try {
return block(closeable)
} catch (throwable: Throwable) {
currentThrowable = throwable as java.lang.Throwable
throw throwable
} finally {
if (currentThrowable != null) {
try {
closeable.close()
} catch (throwable: Throwable) {
currentThrowable.addSuppressed(throwable)
}
} else {
closeable.close()
}
}
}
更新:
由于 mfulton26 pointed out in his kotlin.Throwable
不包含 addSuppressed(Throwable)
方法,因此我们必须将 kotlin.Throwable
转换为 java.lang.Throwable
以使代码正常工作。
我想你想要的是 use()
定义在 Closable
.
自 Kotlin 1.1 起,.use
有一个 AutoCloseable
实现。
@SinceKotlin("1.1")
@Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER")
@kotlin.internal.InlineOnly
public inline fun <T : AutoCloseable?, R> T.use(block: (T) -> R): R {
var exception: Throwable? = null
try {
return block(this)
} catch (e: Throwable) {
exception = e
throw e
} finally {
this.closeFinally(exception)
}
}
复制自source