I have the following method in Java:
public void doSomething() {
final boolean promote = false;
final String bob;
if (promote) {
try(StringWriter sw = new StringWriter()) {
sw.write("this is a test");
bob = sw.toString();
} catch (IOException e) {
e.printStackTrace();
throw new IllegalStateException();
}
} else {
bob = "anaconda";
}
System.out.println(bob);
}
When I convert this to Kotlin:
val promote = false
val bob: String
if (promote) {
try {
StringWriter().use { sw ->
sw.write("this is a test")
bob = sw.toString()
}
} catch (e: IOException) {
e.printStackTrace()
throw IllegalStateException()
}
} else {
bob = "anaconda"
}
println(bob)
But I get a compiler error on the last line: Variable 'bob' must be initialized.
I can't see how Kotlin could fail to initialise the bob
variable when the Java compiler is so sure that the variable has either been initialised or an exception has been thrown.
Is my only option to change bob
to a var
and initialise it?
Assign the result of use
method to the variable like so:
bob = StringWriter().use { sw ->
sw.write("this is a test")
sw.toString()
}
The Java compiler is able to figure out that the variable will be initialised because the try with resources is a language feature. The use
method on the other hand is a library feature with behavior dependent on the implementation that is actually imported and used. In other words the Kotlin compiler has no way of knowing if the function passed as an argument to use
will be invoked immediately or not.
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