问题
Kotlin provides the use
function for Closeable
objects, but it seems they forgot to consider AutoCloseable
(e.g. DB prepared statements) for the try-with-resources full Java equivalent.
I've implemented the next "home-made" solution:
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)
}
}
I'm new to Kotlin and I would like to know if I'm missing something important in my own solution that could give me problems/leakages in a production environment.
回答1:
Your implementation will work fine but it's different from a standard try-with-resources implementation. If you want it to work like in Java you should do something like that:
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()
}
}
}
UPDATE:
As mfulton26 pointed out in his comment kotlin.Throwable
doesn't contain addSuppressed(Throwable)
method so we have to cast kotlin.Throwable
to java.lang.Throwable
to make the code work.
回答2:
Since Kotlin 1.1, .use
has an AutoCloseable
implementation.
@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)
}
}
Copied from source
回答3:
I think what you want is use() as defined on Closable
.
来源:https://stackoverflow.com/questions/36260556/my-own-solution-for-kotlins-try-with-resources-absence