Let's imagine the next piece of Kotlin code that performs some query to a database by means a JDBC connector:
var results : ResultSet
preparedStatement.clearParameters()
preparedStatement.setInt(1,value1);
preparedStatement.setInt(2,value2)
results = preparedStatement.executeQuery()
while(results.next()) {
// parse results
}
that compiles without problems. However, when I try to add thread safety to the access to the preparedStatement:
var results : ResultSet
synchronized(preparedStatement) {
preparedStatement.clearParameters()
preparedStatement.setInt(1,value1);
preparedStatement.setInt(2,value2)
results = preparedStatement.executeQuery()
}
while(results.next()) {
// parse results
}
... I got a "Variable 'results' must be initialized". It seems the synchronized
block acts as a conditional block, but you can be sure that it will be executed once, before the while
block.
I have implemented this same block in Java and I don't get the error. Is this a design/implementation error of Kotlin? Or does it have a good reason to behave like that?
synchronized
is just an inline function and compiler doesn't know if lambda will be executed once, or even executed at all. Idiomatic way is to return value from lambda and assign it to the local:
val results =
synchronized(preparedStatement) {
preparedStatement.clearParameters()
preparedStatement.setInt(1,value1);
preparedStatement.setInt(2,value2)
preparedStatement.executeQuery()
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With